CurvePrimitive
常用的见下
LineSegment3d | 直线段 | 两点直线 | 边、杆件、骨架 |
LineString3d | 折线 | 多点连续直线 | 轮廓线、路径 |
Arc3d | 圆弧 / 椭圆弧 | 圆心 + 半径 + 起止角 | 圆孔、圆角、弧段 |
BezierCurve3d | 贝塞尔曲线 | 端点 + 控制点 | 平滑过渡、动画轨迹 |
BSplineCurve3d | B 样条 / NURBS | 控制点 + 节点矢量 | 车身曲面、流线 |
LineSegment3d
示例代码 LineSegment3d
核心部分,如何创建线段,及如何根据比例取点
一条
LineSegment3d
,由起点pointA
和终点pointB
组成。fraction:一个 归一化参数
0.0
→ 起点1.0
→ 终点0.5
→ 线段中点可超范围:
-0.2
、1.3
等会得到延长线上的点。
import { LineSegment3d, Point3d } from "@itwin/core-geometry";
export default class SimpleLineApi {
public static createLineSegmentFromXY(point1X: number, point1Y: number, point2X: number, point2Y: number): LineSegment3d {
const pointA = Point3d.create(point1X, point1Y, 0);
const pointB = Point3d.create(point2X, point2Y, 0);
return LineSegment3d.create(pointA, pointB);
}
public static createPointsAlongLine(lineSegment: LineSegment3d, fractionsAlongLine: number[]): Point3d[] {
const points: Point3d[] = [];
for (const fractionAlongLine of fractionsAlongLine) {
const pointAlongLine = lineSegment.fractionToPoint(fractionAlongLine);
points.push(pointAlongLine);
}
return points;
}
}
LineString3d
连续线段集合
import { LineString3d, Point3d } from "@itwin/core-geometry";
// 1. 从点数组
const ls = LineString3d.create([
Point3d.create(0, 0, 0),
Point3d.create(1, 2, 3),
Point3d.create(4, 5, 6)
]);
// 2. 两点起止
const ls2 = LineString3d.create(Point3d.create(0,0), Point3d.create(10,0), Point3d.create(10,10));
// 3. 空折线再 push
const ls3 = LineString3d.create();
ls3.pushXYZ(1,2,3);
ls3.pushXYZ(4,5,6);
Arc
Arc3d.create(center, vectorU, vectorV, AngleSweep.createStartEndDegrees(0, 90))
把圆心、半径向量、垂直向量及起止角度交给 Arc3d.create
,即可得到一条位于任意 3D 平面中的圆弧。
参数 | 作用 | 典型取值 |
---|---|---|
center |
圆心坐标 | {x:0, y:0, z:0} |
vectorX |
半径向量 + X 轴方向 | 长度 = 半径,例如 Vector3d.create(5,0,0) |
vectorY |
与 vectorX 垂直,定义平面 | 例如 Vector3d.create(0,5,0) |
sweepStartEnd |
两元素的数组 [startDeg, endDeg] |
[0, 90] 表示 0° 到 90° 的圆弧 |
其余的一些对外函数,所以iTwin并不是只能去获取几何,还有大量的函数
类别 | 函数签名(简写) | 一句话作用 |
---|---|---|
构造函数 | Arc3d.create(center, vector0, vector90, sweep) |
用圆心 + 两正交向量 + 角度范围建圆弧 |
Arc3d.createXY(center, radius, sweep?) |
快速建 X-Y 平面圆弧 | |
Arc3d.createXYZ(center, radius, sweep?) |
快速建 X-Y-Z 空间圆弧 | |
Arc3d.createUnitCircle() |
单位圆(半径 1,0-360°) | |
Arc3d.fromJSON(json) |
反序列化恢复圆弧 | |
Arc3d.createCircularStartMiddleEnd(start, middle, end) |
三点定圆弧 | |
读取属性 | arc.center : Point3d |
圆心坐标 |
arc.vector0 : Vector3d |
0° 方向半径向量 | |
arc.vector90 : Vector3d |
90° 方向半径向量 | |
arc.sweep : AngleSweep |
起止角对象 | |
arc.radiusXY : number |
平均半径 | |
arc.curveLength() |
弧长 | |
arc.fractionToPoint(f) |
比例 0-1 取点 | |
arc.fractionToPointAndDerivative(f) |
取点 + 切线 | |
arc.closestPoint(spacePt) |
空间点到圆弧最近点 | |
arc.isCircular : boolean |
是否整圆(360°) | |
变换 / 复制 | arc.clone() |
深拷贝 |
arc.cloneTransformed(transform) |
变换后拷贝 | |
arc.reverseInPlace() |
就地反转起止角 | |
几何操作 | arc.constructOffset(distance, method?) |
生成等距圆弧 |
arc.constructCircularArcChainApproximation(options) |
圆弧 → 多段小圆弧近似 | |
arc.extendToStartEnd(start, end) |
延伸/裁剪到起止点 | |
arc.getRange() |
返回包围盒 Range3d |
|
交互 / 判断 | arc.isAlmostEqual(other) |
几何相等比较 |
arc.intersectRay3d(ray) |
与射线求交 | |
arc.intersectPlane(plane) |
与平面求交 | |
arc.intersectRange(range) |
与包围盒求交 |
BezierCurve3d
不好意思这个例子很多函数名没改。。。。但是我不想改了。。
伯恩斯坦多项式
成员 | 返回值 | 一句话作用 |
---|---|---|
curve.controlPoints : Point3d[] |
控制点数组 | 直接拿到当前控制点 |
curve.order : number |
阶数 | 2=二次,3=立方 |
curve.curveLength() |
近似弧长 | 快速积分长度 |
curve.fractionToPoint(f) |
Point3d |
比例 0-1 取点 |
curve.fractionToPointAndDerivative(f) |
{point,derivative} |
取点 + 切线 |
curve.closestPoint(spacePt) |
{point,fraction} |
空间点到曲线最近 |
BSplineCurve3d
Loop
是由折线(或任意曲线链)首尾闭合形成的“环”,比如面域边界、孔洞、截面轮廓
把折线变 Loop(强制闭合)
import { Loop, LineString3d } from "@itwin/core-geometry";
const ls = LineString3d.create([p0, p1, p2, p0]); // 首尾同点
const loop = Loop.create(ls); // 生成闭合环
从 Loop 取回折线
const lsAgain = loop.children[0] as LineString3d;
Path
Path 是一个可以混装任意曲线类型,不强制闭合的 开放曲线链(poly-curve),比如布线、扫描路径、拉伸轨迹。它只表示一条“路径”,不包围任何区域;若要围成区域,请用 Loop。
会把多种线类型,如线段和弧,拼接成一个Path,然后用Decorator来渲染,用作路径展示之类
import { LineString3d, Arc3d, Path } from "@itwin/core-geometry";
const ls = LineString3d.create([p0, p1]);
const arc = Arc3d.createXY(Point3d.create(2,0), 3);
const path = Path.create(ls, arc); // 折线 + 圆弧 连成开放链
console.log(path.curveLength());