向量与颜色(Vector)
向量与颜色是内建七型族:vec2 / vec3 / vec4(float 分量)、vec2i / vec3i / vec4i(int 分量)、color(rgba 四个 float 分量,约定 0..1 域,运行时不钳制)。
构造
调用构造,new 对向量与颜色不可用:
val v = vec2(1.0, 2.0);
print(v);
print(vec2(1.0));
print(vec2i(v));
val c = color("#ff8000");
print(c);
print(color(1.0, 0.5, 0.25));
print(color(0.25));vec2(1.0, 2.0)
vec2(1.0, 1.0)
vec2i(1, 2)
color(1.0, 0.502, 0.0, 1.0)
color(1.0, 0.5, 0.25, 1.0)
color(0.25, 0.25, 0.25, 0.25)- 单数值参是广播(
vec2(1.0)得(1.0, 1.0));单向量实参做同维族间转换(float 向 int 向零截断)。 - color 收三参(alpha 缺省 1.0)或四参;也收 hex 字符串(
#RGB/#RGBA/#RRGGBB/#RRGGBBAA)。 - color 分量实参必须 float,int 被拒。想用 8 位值可以写 hex 字符串。
分量与 swizzle
双字母表纪律:vec 族分量是 xyzw,color 分量是 rgba,两套字母表不得混用。swizzle 取 1 到 4 个字母,结果一律按 xyzw 字母表解释(c.rgb.y 取的是绿分量):
print(c.rgb);
print(c.rgb.y);
print(v[1]);
val (x, y) = vec2i(3, 4);
print(x, y);vec3(1.0, 0.502, 0.0)
0.5019608
2
3 4数字下标 v[1] 是断言形,越界会直接硬错。Get(i) 是对应的 fail 形:越界 fail IndexOutOfRange,try? 消费后越界得 null,命中则得分量值(vec2i 族是 int,vec/vec3/vec4 与 color 是 float):
print(try? v.Get(1), try? v.Get(9));
print(try? c.Get(3) ?? 0.0);2 null
1分量只读:v.x = 1.0 与写侧 swizzle 编译期拒绝。改值唯一写法是非破坏性更新(见struct的 with 一节):
val moved = v with { x: 9.0 };
print(moved);vec2(9.0, 2.0)算术
+ - * / 逐分量(同型之间)。标量可以在任意一侧参与乘除,标量在左的 - 与 / 是反向逐分量:1.0 / vec2(2.0, 4.0) 得 vec2(0.5, 0.25)。== / != 按值判等。不能进行序比较、位运算以及幂运算。
方法面
方法内建分派,不依赖 import:
| 成员 | 适用 | 说明 |
|---|---|---|
Length | vec 族 | 模长,属性形(不带括号) |
Dot / Distance | vec 族 | 点积 / 两点距离 |
Normalized | vec 族 | 单位化 |
Cross | 仅 vec3 | 叉积 |
Lerp | vec 族 | 按系数插值 |
Hex | 仅 color | 转 hex 串(含 alpha,#ff8000ff) |
ToHsv / FromHsv | color / vec3 | hsv 三通道约定 0..1,越域钳制 |
print(v.Length);
print(vec2(1.0, 0.0).Dot(vec2(0.0, 1.0)));
print(vec2(1.0, 2.0).Lerp(vec2(3.0, 4.0), 0.5));
print(c.Hex());2.23606797749979
0
vec2(2.0, 3.0)
#ff8000ff编译期折叠
纯字面量的构造、一元负、四则与 swizzle 链在编译期折成常量。const 位同样支持:const V = vec2(1.0, 2.0); 合法,V.x 就是 1(见常量方法)。color 的单 string 实参在 const 位走编译期 hex 解析。
注意
- color 的 0..1 是约定域,运行时不钳制:写
color(2.0, 0.5, 0.25)合法,超出部分由渲染端解释。 - match 构造模式臂支持向量(
vec2(1.0, 0.0) => ...),见模式。
最后更新于 2026年10月10日
