Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

VItem

Caution

ai 生成,可能叙事逻辑和表述并不是很好,仅供参考。

pub struct VItem {
    pub normal: Option<DVec3>,        // 投影平面法向;None 时渲染时推导
    pub vpoints: VPointVec,           // 点列(二次贝塞尔)
    pub stroke_widths: PointVec<Width>,
    pub stroke_rgbas: PointVec<Rgba>,
    pub fill_rgbas: PointVec<Rgba>,
}

vpoints:二次贝塞尔路径

vpoints 是 anchor 与 handle 交替排列的点列:[a₀, h₀, a₁, h₁, a₂, …], 每三个连续点 (aᵢ, hᵢ, aᵢ₊₁) 构成一段二次贝塞尔。颜色与线宽数组按段 对齐(长度 = 点数 / 2 向上取整),因此可以给一个 item 的不同段设置不同 颜色/线宽。

// 直接用点列构造(默认:白描边 0.02、无填充)
let vitem = VItem::from_vpoints(vec![
    dvec3(0.0, 0.0, 0.0),
    dvec3(1.0, 0.0, 0.0),
    dvec3(0.5, 1.0, 0.0),
]);

常用方法:close()(闭合路径)、shrink()(缩到包围盒中心)、 get_anchor(idx)(取第 idx 个 anchor)、extend_vpoints(...)(追加,颜色/ 线宽数组自动补齐)、put_start_and_end_on(start, end)(把首尾移到指定位 置)、with_normal(...) / set_normal(...)(指定投影平面法向)。

渲染语义:平面投影

渲染时假设 VItem 的所有点共面,实际渲染的是它在投影平面上的投影 (共面时投影即其本身)。语义细节见 Core Items 的 VItem。

normal 一般保持默认的 None 即可:投影平面在渲染时从当前点数据推导, 动画中间帧的插值点总是推导出与之一致的法向,不会漂移。反之,显式 set_normal 之后,插值就发生在法向量本身上(Some(a).lerp(Some(b), t), 普通线性插值且不重新归一化),不再跟随点数据。因此只在确有需要时才显式 设置,例如点共线/重合等自动推导存在歧义的退化情形,或故意要让非共面点 渲染成投影效果。

动画相关 trait

VItem 实现了 Interpolatable(逐点/逐颜色插值)与 Alignable(点数不同 时自动补齐对齐,morph 依赖它),因此可以直接:

let anim = square.morph(|sq| {
    sq.set_fill_color(manim::BLUE_C);
    sq.shift(DVec3::X * 2.0);
});

还实现了 FillColor / StrokeColor / StrokeWidth / Opacity / Partial(get_partial(range) 截取路径的一段,Create/Write 动画的 基础)、PointsFunc(apply_points_func 批量变换点)、Aabb 与 ShiftTransform / RotateTransform / ScaleTransform。

PointVec 是分量数组的动画包装:对齐时按规则补齐长度,插值逐分量进行。