@ccpc/math 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/constants/geom_type.d.ts +13 -0
- package/dist/constants/geom_type.d.ts.map +1 -0
- package/dist/constants/geom_type.js +17 -0
- package/dist/constants/math_const.d.ts +9 -0
- package/dist/constants/math_const.d.ts.map +1 -0
- package/dist/constants/math_const.js +12 -0
- package/dist/core/box2.d.ts +71 -0
- package/dist/core/box2.d.ts.map +1 -0
- package/dist/core/box2.js +243 -0
- package/dist/core/coord2d.d.ts +62 -0
- package/dist/core/coord2d.d.ts.map +1 -0
- package/dist/core/coord2d.js +155 -0
- package/dist/core/geom_base.d.ts +19 -0
- package/dist/core/geom_base.d.ts.map +1 -0
- package/dist/core/geom_base.js +18 -0
- package/dist/core/mat3.d.ts +101 -0
- package/dist/core/mat3.d.ts.map +1 -0
- package/dist/core/mat3.js +290 -0
- package/dist/core/vec2.d.ts +138 -0
- package/dist/core/vec2.d.ts.map +1 -0
- package/dist/core/vec2.js +297 -0
- package/dist/curves/arc2.d.ts +49 -0
- package/dist/curves/arc2.d.ts.map +1 -0
- package/dist/curves/arc2.js +265 -0
- package/dist/curves/bspline2.d.ts +150 -0
- package/dist/curves/bspline2.d.ts.map +1 -0
- package/dist/curves/bspline2.js +793 -0
- package/dist/curves/circle2.d.ts +42 -0
- package/dist/curves/circle2.d.ts.map +1 -0
- package/dist/curves/circle2.js +135 -0
- package/dist/curves/circle_curve2.d.ts +38 -0
- package/dist/curves/circle_curve2.d.ts.map +1 -0
- package/dist/curves/circle_curve2.js +112 -0
- package/dist/curves/curve2.d.ts +214 -0
- package/dist/curves/curve2.d.ts.map +1 -0
- package/dist/curves/curve2.js +238 -0
- package/dist/curves/ellipse2.d.ts +42 -0
- package/dist/curves/ellipse2.d.ts.map +1 -0
- package/dist/curves/ellipse2.js +125 -0
- package/dist/curves/ellipse_arc2.d.ts +49 -0
- package/dist/curves/ellipse_arc2.d.ts.map +1 -0
- package/dist/curves/ellipse_arc2.js +184 -0
- package/dist/curves/ellipse_curve2.d.ts +56 -0
- package/dist/curves/ellipse_curve2.d.ts.map +1 -0
- package/dist/curves/ellipse_curve2.js +262 -0
- package/dist/curves/interval.d.ts +112 -0
- package/dist/curves/interval.d.ts.map +1 -0
- package/dist/curves/interval.js +200 -0
- package/dist/curves/line2.d.ts +64 -0
- package/dist/curves/line2.d.ts.map +1 -0
- package/dist/curves/line2.js +193 -0
- package/dist/curves/period_interval.d.ts +129 -0
- package/dist/curves/period_interval.d.ts.map +1 -0
- package/dist/curves/period_interval.js +240 -0
- package/dist/discretize/discretize_defaults.d.ts +12 -0
- package/dist/discretize/discretize_defaults.d.ts.map +1 -0
- package/dist/discretize/discretize_defaults.js +12 -0
- package/dist/discretize/discretize_engine.d.ts +33 -0
- package/dist/discretize/discretize_engine.d.ts.map +1 -0
- package/dist/discretize/discretize_engine.js +347 -0
- package/dist/discretize/discretize_errors.d.ts +15 -0
- package/dist/discretize/discretize_errors.d.ts.map +1 -0
- package/dist/discretize/discretize_errors.js +30 -0
- package/dist/discretize/discretize_options.d.ts +18 -0
- package/dist/discretize/discretize_options.d.ts.map +1 -0
- package/dist/discretize/discretize_options.js +19 -0
- package/dist/discretize/discretize_types.d.ts +36 -0
- package/dist/discretize/discretize_types.d.ts.map +1 -0
- package/dist/discretize/discretize_types.js +1 -0
- package/dist/discretize/internal/curve_guards.d.ts +35 -0
- package/dist/discretize/internal/curve_guards.d.ts.map +1 -0
- package/dist/discretize/internal/curve_guards.js +62 -0
- package/dist/discretize/internal/postprocess.d.ts +5 -0
- package/dist/discretize/internal/postprocess.d.ts.map +1 -0
- package/dist/discretize/internal/postprocess.js +109 -0
- package/dist/discretize/internal/sampling_utils.d.ts +8 -0
- package/dist/discretize/internal/sampling_utils.d.ts.map +1 -0
- package/dist/discretize/internal/sampling_utils.js +36 -0
- package/dist/discretize/register_builtin_strategies.d.ts +3 -0
- package/dist/discretize/register_builtin_strategies.d.ts.map +1 -0
- package/dist/discretize/register_builtin_strategies.js +10 -0
- package/dist/discretize/strategies/bspline_strategy.d.ts +4 -0
- package/dist/discretize/strategies/bspline_strategy.d.ts.map +1 -0
- package/dist/discretize/strategies/bspline_strategy.js +115 -0
- package/dist/discretize/strategies/circle_strategy.d.ts +7 -0
- package/dist/discretize/strategies/circle_strategy.d.ts.map +1 -0
- package/dist/discretize/strategies/circle_strategy.js +55 -0
- package/dist/discretize/strategies/ellipse_strategy.d.ts +7 -0
- package/dist/discretize/strategies/ellipse_strategy.d.ts.map +1 -0
- package/dist/discretize/strategies/ellipse_strategy.js +86 -0
- package/dist/discretize/strategies/line_strategy.d.ts +4 -0
- package/dist/discretize/strategies/line_strategy.d.ts.map +1 -0
- package/dist/discretize/strategies/line_strategy.js +40 -0
- package/dist/discretize/strategy_registry.d.ts +9 -0
- package/dist/discretize/strategy_registry.d.ts.map +1 -0
- package/dist/discretize/strategy_registry.js +34 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/intersections/analytic_x_algorithm.d.ts +10 -0
- package/dist/intersections/analytic_x_algorithm.d.ts.map +1 -0
- package/dist/intersections/analytic_x_algorithm.js +83 -0
- package/dist/intersections/curve_x_engine.d.ts +9 -0
- package/dist/intersections/curve_x_engine.d.ts.map +1 -0
- package/dist/intersections/curve_x_engine.js +27 -0
- package/dist/intersections/index.d.ts +5 -0
- package/dist/intersections/index.d.ts.map +1 -0
- package/dist/intersections/index.js +11 -0
- package/dist/intersections/internal/certification.d.ts +34 -0
- package/dist/intersections/internal/certification.d.ts.map +1 -0
- package/dist/intersections/internal/certification.js +238 -0
- package/dist/intersections/internal/interval_clipping.d.ts +29 -0
- package/dist/intersections/internal/interval_clipping.d.ts.map +1 -0
- package/dist/intersections/internal/interval_clipping.js +123 -0
- package/dist/intersections/internal/kind.d.ts +4 -0
- package/dist/intersections/internal/kind.d.ts.map +1 -0
- package/dist/intersections/internal/kind.js +16 -0
- package/dist/intersections/internal/pair.d.ts +9 -0
- package/dist/intersections/internal/pair.d.ts.map +1 -0
- package/dist/intersections/internal/pair.js +14 -0
- package/dist/intersections/internal/result.d.ts +20 -0
- package/dist/intersections/internal/result.d.ts.map +1 -0
- package/dist/intersections/internal/result.js +125 -0
- package/dist/intersections/internal/sampling.d.ts +15 -0
- package/dist/intersections/internal/sampling.d.ts.map +1 -0
- package/dist/intersections/internal/sampling.js +131 -0
- package/dist/intersections/internal/segment.d.ts +32 -0
- package/dist/intersections/internal/segment.d.ts.map +1 -0
- package/dist/intersections/internal/segment.js +137 -0
- package/dist/intersections/internal/tolerance.d.ts +10 -0
- package/dist/intersections/internal/tolerance.d.ts.map +1 -0
- package/dist/intersections/internal/tolerance.js +20 -0
- package/dist/intersections/intersector.d.ts +6 -0
- package/dist/intersections/intersector.d.ts.map +1 -0
- package/dist/intersections/intersector.js +1 -0
- package/dist/intersections/numeric_x_algorithm.d.ts +10 -0
- package/dist/intersections/numeric_x_algorithm.d.ts.map +1 -0
- package/dist/intersections/numeric_x_algorithm.js +73 -0
- package/dist/intersections/solvers/bspline_self_solver.d.ts +7 -0
- package/dist/intersections/solvers/bspline_self_solver.d.ts.map +1 -0
- package/dist/intersections/solvers/bspline_self_solver.js +308 -0
- package/dist/intersections/solvers/line_line_pair_solver.d.ts +7 -0
- package/dist/intersections/solvers/line_line_pair_solver.d.ts.map +1 -0
- package/dist/intersections/solvers/line_line_pair_solver.js +35 -0
- package/dist/intersections/solvers/pair_solvers.d.ts +94 -0
- package/dist/intersections/solvers/pair_solvers.d.ts.map +1 -0
- package/dist/intersections/solvers/pair_solvers.js +1078 -0
- package/dist/intersections/solvers/polyline_pair_intersector.d.ts +51 -0
- package/dist/intersections/solvers/polyline_pair_intersector.d.ts.map +1 -0
- package/dist/intersections/solvers/polyline_pair_intersector.js +731 -0
- package/dist/intersections/types.d.ts +11 -0
- package/dist/intersections/types.d.ts.map +1 -0
- package/dist/intersections/types.js +1 -0
- package/dist/serialize/dump_types.d.ts +101 -0
- package/dist/serialize/dump_types.d.ts.map +1 -0
- package/dist/serialize/dump_types.js +5 -0
- package/dist/serialize/geom_mgr.d.ts +24 -0
- package/dist/serialize/geom_mgr.d.ts.map +1 -0
- package/dist/serialize/geom_mgr.js +30 -0
- package/dist/types/type_define.d.ts +29 -0
- package/dist/types/type_define.d.ts.map +1 -0
- package/dist/types/type_define.js +10 -0
- package/dist/types/type_guard.d.ts +46 -0
- package/dist/types/type_guard.d.ts.map +1 -0
- package/dist/types/type_guard.js +5 -0
- package/dist/utils/math_error.d.ts +16 -0
- package/dist/utils/math_error.d.ts.map +1 -0
- package/dist/utils/math_error.js +35 -0
- package/dist/utils/math_utils.d.ts +9 -0
- package/dist/utils/math_utils.d.ts.map +1 -0
- package/dist/utils/math_utils.js +25 -0
- package/dist/utils/precision.d.ts +29 -0
- package/dist/utils/precision.d.ts.map +1 -0
- package/dist/utils/precision.js +44 -0
- package/package.json +38 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { EN_GEO_TYPE } from '../constants/geom_type';
|
|
2
|
+
import { Box2 } from '../core/box2';
|
|
3
|
+
import { Mat3 } from '../core/mat3';
|
|
4
|
+
import { Vec2 } from '../core/vec2';
|
|
5
|
+
import type { IDBLine2 } from '../serialize/dump_types';
|
|
6
|
+
import type { IClosestPointResult } from '../types/type_define';
|
|
7
|
+
import { Curve2 } from './curve2';
|
|
8
|
+
import { Interval } from './interval';
|
|
9
|
+
export declare class Line2 extends Curve2 {
|
|
10
|
+
static readonly type = EN_GEO_TYPE.Line2;
|
|
11
|
+
private _start;
|
|
12
|
+
private _end;
|
|
13
|
+
private _dir;
|
|
14
|
+
private _len;
|
|
15
|
+
/**
|
|
16
|
+
* 构造线段。
|
|
17
|
+
* @param start 起点。
|
|
18
|
+
* @param end 终点。
|
|
19
|
+
*/
|
|
20
|
+
constructor(start: Vec2, end: Vec2);
|
|
21
|
+
/** 起点(返回副本) */
|
|
22
|
+
get start(): Vec2;
|
|
23
|
+
/** 终点(返回副本) */
|
|
24
|
+
get end(): Vec2;
|
|
25
|
+
pointAt(u: number): Vec2;
|
|
26
|
+
tangentAt(u: number): Vec2;
|
|
27
|
+
derivatives(u: number, n: number): Vec2[];
|
|
28
|
+
curvatureAt(u: number): number;
|
|
29
|
+
length(range?: Interval): number;
|
|
30
|
+
lengthAtParam(u: number): number;
|
|
31
|
+
paramAtLength(s: number, tol?: number): number;
|
|
32
|
+
split(u: number): Line2[];
|
|
33
|
+
trim(range: Interval): Line2[];
|
|
34
|
+
reverse(): this;
|
|
35
|
+
transform(m: Mat3): this;
|
|
36
|
+
transformed(m: Mat3): this;
|
|
37
|
+
closestPoint(p: Vec2): IClosestPointResult;
|
|
38
|
+
boundingBox(): Box2;
|
|
39
|
+
isValid(eps?: number): boolean;
|
|
40
|
+
isLine(): this is Line2;
|
|
41
|
+
/**
|
|
42
|
+
* 结构等价判断(字段级)。
|
|
43
|
+
* @param other 对比线段。
|
|
44
|
+
* @param eps 数值容差。
|
|
45
|
+
* @returns 起点与终点分别近似相等时返回 `true`。
|
|
46
|
+
*/
|
|
47
|
+
equals(other: Line2, eps?: number): boolean;
|
|
48
|
+
clone(): this;
|
|
49
|
+
dump(): IDBLine2;
|
|
50
|
+
static load(data: IDBLine2): Line2;
|
|
51
|
+
/**
|
|
52
|
+
* 参数吸附到端点,避免边界浮点抖动。
|
|
53
|
+
* @param u 输入参数。
|
|
54
|
+
* @returns 吸附后的参数。
|
|
55
|
+
*/
|
|
56
|
+
private snapParam;
|
|
57
|
+
/**
|
|
58
|
+
* 重建方向与长度缓存。
|
|
59
|
+
* - `_dir`:单位方向向量
|
|
60
|
+
* - `_len`:线段长度
|
|
61
|
+
*/
|
|
62
|
+
private rebuildCache;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=line2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line2.d.ts","sourceRoot":"","sources":["../../src/curves/line2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,qBAKa,KAAM,SAAQ,MAAM;IAC7B,gBAAuB,IAAI,qBAAoB;IAE/C,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,IAAI,CAAQ;IAEpB;;;;OAIG;gBACS,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;IAUlC,eAAe;IACf,IAAW,KAAK,SAEf;IAED,eAAe;IACf,IAAW,GAAG,SAEb;IAEe,OAAO,CAAC,CAAC,EAAE,MAAM;IAKjB,SAAS,CAAC,CAAC,EAAE,MAAM;IAKnB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAShC,WAAW,CAAC,CAAC,EAAE,MAAM;IAKrB,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ;IAMvB,aAAa,CAAC,CAAC,EAAE,MAAM;IAIvB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAA6B;IAMzD,KAAK,CAAC,CAAC,EAAE,MAAM;IAWf,IAAI,CAAC,KAAK,EAAE,QAAQ;IAUpB,OAAO;IASP,SAAS,CAAC,CAAC,EAAE,IAAI;IAcjB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAI1B,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,mBAAmB;IAW1C,WAAW;IAIX,OAAO,CAAC,GAAG,SAA6B;IAQxC,MAAM,IAAI,IAAI,IAAI,KAAK;IAIvC;;;;;OAKG;IACI,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,SAAgB;IAI/B,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,QAAQ;WAQlB,IAAI,CAAC,IAAI,EAAE,QAAQ;IAOjC;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAOvB"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var Line2_1;
|
|
8
|
+
import { EN_GEO_TYPE } from '../constants/geom_type';
|
|
9
|
+
import { Box2 } from '../core/box2';
|
|
10
|
+
import { Vec2 } from '../core/vec2';
|
|
11
|
+
import { RegisterGeom } from '../serialize/geom_mgr';
|
|
12
|
+
import { MathError } from '../utils/math_error';
|
|
13
|
+
import { Precision } from '../utils/precision';
|
|
14
|
+
import { Curve2 } from './curve2';
|
|
15
|
+
import { Interval } from './interval';
|
|
16
|
+
let Line2 = Line2_1 = class Line2 extends Curve2 {
|
|
17
|
+
/**
|
|
18
|
+
* 构造线段。
|
|
19
|
+
* @param start 起点。
|
|
20
|
+
* @param end 终点。
|
|
21
|
+
*/
|
|
22
|
+
constructor(start, end) {
|
|
23
|
+
super();
|
|
24
|
+
this._start = start.clone();
|
|
25
|
+
this._end = end.clone();
|
|
26
|
+
this._dir = Vec2.zero();
|
|
27
|
+
this._len = 0;
|
|
28
|
+
this.rebuildCache();
|
|
29
|
+
this.setRange(new Interval(0, this._len));
|
|
30
|
+
}
|
|
31
|
+
/** 起点(返回副本) */
|
|
32
|
+
get start() {
|
|
33
|
+
return this._start.clone();
|
|
34
|
+
}
|
|
35
|
+
/** 终点(返回副本) */
|
|
36
|
+
get end() {
|
|
37
|
+
return this._end.clone();
|
|
38
|
+
}
|
|
39
|
+
pointAt(u) {
|
|
40
|
+
const uu = this.snapParam(u);
|
|
41
|
+
return this._start.added(this._dir.scaled(uu));
|
|
42
|
+
}
|
|
43
|
+
tangentAt(u) {
|
|
44
|
+
this.snapParam(u);
|
|
45
|
+
return this._dir.clone();
|
|
46
|
+
}
|
|
47
|
+
derivatives(u, n) {
|
|
48
|
+
MathError.assert(Number.isInteger(n) && n >= 0, 'Line2.derivatives: n must be a non-negative integer');
|
|
49
|
+
const ret = [this.pointAt(u)];
|
|
50
|
+
for (let i = 1; i <= n; i++) {
|
|
51
|
+
ret.push(i === 1 ? this._dir.clone() : Vec2.zero());
|
|
52
|
+
}
|
|
53
|
+
return ret;
|
|
54
|
+
}
|
|
55
|
+
curvatureAt(u) {
|
|
56
|
+
this.snapParam(u);
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
length(range) {
|
|
60
|
+
if (!range)
|
|
61
|
+
return this._len;
|
|
62
|
+
this._range.assertContainsRange(range, Precision.CURVE_PARAM_EPS);
|
|
63
|
+
return range.length();
|
|
64
|
+
}
|
|
65
|
+
lengthAtParam(u) {
|
|
66
|
+
return this.snapParam(u);
|
|
67
|
+
}
|
|
68
|
+
paramAtLength(s, tol = Precision.CURVE_LENGTH_EPS) {
|
|
69
|
+
MathError.assert(Number.isFinite(tol) && tol > 0, 'Line2.paramAtLength: tol must be > 0');
|
|
70
|
+
MathError.assert(s >= -tol && s <= this._len + tol, `Line2.paramAtLength: s out of range [0, ${this._len}]`);
|
|
71
|
+
return Math.min(this._len, Math.max(0, s));
|
|
72
|
+
}
|
|
73
|
+
split(u) {
|
|
74
|
+
const splitParts = this._range.split(u, Precision.CURVE_PARAM_EPS);
|
|
75
|
+
if (splitParts.length === 0)
|
|
76
|
+
return [];
|
|
77
|
+
const p = this.pointAt(u);
|
|
78
|
+
const left = new Line2_1(this._start, p);
|
|
79
|
+
const right = new Line2_1(p, this._end);
|
|
80
|
+
return [left, right].filter((seg) => seg.length() > Precision.CURVE_LENGTH_EPS);
|
|
81
|
+
}
|
|
82
|
+
trim(range) {
|
|
83
|
+
this._range.assertContainsRange(range, Precision.CURVE_PARAM_EPS);
|
|
84
|
+
if (range.length() <= Precision.CURVE_PARAM_EPS)
|
|
85
|
+
return [];
|
|
86
|
+
if (range.length() <= Precision.CURVE_LENGTH_EPS)
|
|
87
|
+
return [];
|
|
88
|
+
const s = this.pointAt(range.start);
|
|
89
|
+
const e = this.pointAt(range.end);
|
|
90
|
+
return [new Line2_1(s, e)];
|
|
91
|
+
}
|
|
92
|
+
reverse() {
|
|
93
|
+
const t = this._start;
|
|
94
|
+
this._start = this._end;
|
|
95
|
+
this._end = t;
|
|
96
|
+
this.rebuildCache();
|
|
97
|
+
this.setRange(new Interval(0, this._len));
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
transform(m) {
|
|
101
|
+
const newStart = m.transformedPoint(this._start);
|
|
102
|
+
const newEnd = m.transformedPoint(this._end);
|
|
103
|
+
const nextLen = newStart.distanceTo(newEnd);
|
|
104
|
+
MathError.assert(nextLen > Precision.CURVE_LENGTH_EPS, 'Line2.transform: degenerate line after transform');
|
|
105
|
+
this._start = newStart;
|
|
106
|
+
this._end = newEnd;
|
|
107
|
+
this.rebuildCache();
|
|
108
|
+
this.setRange(new Interval(0, this._len));
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
transformed(m) {
|
|
112
|
+
return this.clone().transform(m);
|
|
113
|
+
}
|
|
114
|
+
closestPoint(p) {
|
|
115
|
+
const sp = p.subtracted(this._start);
|
|
116
|
+
const u = Math.min(this._len, Math.max(0, sp.dot(this._dir)));
|
|
117
|
+
const point = this.pointAt(u);
|
|
118
|
+
return {
|
|
119
|
+
point,
|
|
120
|
+
param: u,
|
|
121
|
+
distance: point.distanceTo(p),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
boundingBox() {
|
|
125
|
+
return Box2.fromPoints([this._start, this._end]);
|
|
126
|
+
}
|
|
127
|
+
isValid(eps = Precision.CURVE_LENGTH_EPS) {
|
|
128
|
+
return Number.isFinite(this._start.x) &&
|
|
129
|
+
Number.isFinite(this._start.y) &&
|
|
130
|
+
Number.isFinite(this._end.x) &&
|
|
131
|
+
Number.isFinite(this._end.y) &&
|
|
132
|
+
this._start.distanceTo(this._end) > eps;
|
|
133
|
+
}
|
|
134
|
+
isLine() {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 结构等价判断(字段级)。
|
|
139
|
+
* @param other 对比线段。
|
|
140
|
+
* @param eps 数值容差。
|
|
141
|
+
* @returns 起点与终点分别近似相等时返回 `true`。
|
|
142
|
+
*/
|
|
143
|
+
equals(other, eps = Precision.EPS) {
|
|
144
|
+
return this._start.equals(other._start, eps) && this._end.equals(other._end, eps);
|
|
145
|
+
}
|
|
146
|
+
clone() {
|
|
147
|
+
return new Line2_1(this._start, this._end);
|
|
148
|
+
}
|
|
149
|
+
dump() {
|
|
150
|
+
return {
|
|
151
|
+
type: Line2_1.type,
|
|
152
|
+
start: { x: this._start.x, y: this._start.y },
|
|
153
|
+
end: { x: this._end.x, y: this._end.y },
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
static load(data) {
|
|
157
|
+
return new Line2_1(new Vec2(data.start.x, data.start.y), new Vec2(data.end.x, data.end.y));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 参数吸附到端点,避免边界浮点抖动。
|
|
161
|
+
* @param u 输入参数。
|
|
162
|
+
* @returns 吸附后的参数。
|
|
163
|
+
*/
|
|
164
|
+
snapParam(u) {
|
|
165
|
+
this._range.assertContains(u, Precision.CURVE_PARAM_EPS);
|
|
166
|
+
if (Math.abs(u - this._range.start) <= Precision.CURVE_PARAM_EPS)
|
|
167
|
+
return this._range.start;
|
|
168
|
+
if (Math.abs(u - this._range.end) <= Precision.CURVE_PARAM_EPS)
|
|
169
|
+
return this._range.end;
|
|
170
|
+
return u;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 重建方向与长度缓存。
|
|
174
|
+
* - `_dir`:单位方向向量
|
|
175
|
+
* - `_len`:线段长度
|
|
176
|
+
*/
|
|
177
|
+
rebuildCache() {
|
|
178
|
+
const v = this._end.subtracted(this._start);
|
|
179
|
+
const len = v.len();
|
|
180
|
+
MathError.assert(len > Precision.CURVE_LENGTH_EPS, 'Line2: start and end must not coincide');
|
|
181
|
+
this._len = len;
|
|
182
|
+
this._dir = v.scale(1 / len);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
Line2.type = EN_GEO_TYPE.Line2;
|
|
186
|
+
Line2 = Line2_1 = __decorate([
|
|
187
|
+
RegisterGeom
|
|
188
|
+
/**
|
|
189
|
+
* 二维线段曲线。
|
|
190
|
+
* 参数域固定为 `[0, len]`,其中 `len = |end - start|`。
|
|
191
|
+
*/
|
|
192
|
+
], Line2);
|
|
193
|
+
export { Line2 };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Interval } from './interval';
|
|
2
|
+
export declare class PeriodInterval extends Interval {
|
|
3
|
+
/** 周期长度,必须 > 0 */
|
|
4
|
+
readonly period: number;
|
|
5
|
+
/**
|
|
6
|
+
* 创建周期区间。
|
|
7
|
+
* @param start 区间起点,可为任意实数。
|
|
8
|
+
* @param end 区间终点,可为任意实数。
|
|
9
|
+
* @param period 周期长度,必须大于 0。
|
|
10
|
+
*/
|
|
11
|
+
constructor(start?: number, end?: number, period?: number);
|
|
12
|
+
/**
|
|
13
|
+
* 将参数归一化到 `[0, period)`。
|
|
14
|
+
* @param u 待归一化参数。
|
|
15
|
+
* @returns 归一化后的参数值。
|
|
16
|
+
*/
|
|
17
|
+
normalize(u: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* 将参数归一化到指定周期窗口 `[start, start + period)`。
|
|
20
|
+
* @param u 待归一化参数。
|
|
21
|
+
* @param start 周期窗口起点,默认当前区间起点。
|
|
22
|
+
* @returns 与 `u` 周期等价,且落在窗口内的参数。
|
|
23
|
+
*/
|
|
24
|
+
normalizeInPeriod(u: number, start?: number): number;
|
|
25
|
+
/**
|
|
26
|
+
* 区间整体平移(按周期等价)。
|
|
27
|
+
* @param offset 平移量。
|
|
28
|
+
* @returns 平移后的新区间实例。
|
|
29
|
+
*/
|
|
30
|
+
shift(offset: number): PeriodInterval;
|
|
31
|
+
/**
|
|
32
|
+
* 计算周期区间长度(沿正方向)。
|
|
33
|
+
* @returns 区间跨度,范围在 `[0, period]`。
|
|
34
|
+
*/
|
|
35
|
+
length(): number;
|
|
36
|
+
/**
|
|
37
|
+
* 判断参数是否落在周期区间内。
|
|
38
|
+
* @param u 待判断参数。
|
|
39
|
+
* @param eps 边界比较容差。
|
|
40
|
+
* @returns 落在区间内(含容差)返回 `true`。
|
|
41
|
+
*/
|
|
42
|
+
contains(u: number, eps?: number): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* 将参数限制到区间内。
|
|
45
|
+
* @param u 输入参数。
|
|
46
|
+
* @returns 已在区间内返回归一化参数;否则返回最近边界参数。
|
|
47
|
+
*/
|
|
48
|
+
clamp(u: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* 判断两个周期区间是否近似相等。
|
|
51
|
+
* @param other 对比区间。
|
|
52
|
+
* @param eps 数值比较容差。
|
|
53
|
+
* @returns 周期一致且区间位置/长度一致时返回 `true`。
|
|
54
|
+
*/
|
|
55
|
+
equals(other: PeriodInterval, eps?: number): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* 计算周期交集。
|
|
58
|
+
* @param other 参与求交的周期区间。
|
|
59
|
+
* @param eps 交并判定容差。
|
|
60
|
+
* @returns 交集结果,按线性分段返回 `PeriodInterval[]`(最多 2 段)。
|
|
61
|
+
*/
|
|
62
|
+
intersect(other: PeriodInterval, eps?: number): PeriodInterval[];
|
|
63
|
+
/**
|
|
64
|
+
* 计算周期并集。
|
|
65
|
+
* @param other 参与求并的周期区间。
|
|
66
|
+
* @param eps 交并判定容差。
|
|
67
|
+
* @returns 并集结果,按线性分段返回 `PeriodInterval[]`(1 到 2 段)。
|
|
68
|
+
*/
|
|
69
|
+
union(other: PeriodInterval, eps?: number): PeriodInterval[];
|
|
70
|
+
/**
|
|
71
|
+
* 以参数 `u` 对周期区间切分。
|
|
72
|
+
* @param u 切分参数。
|
|
73
|
+
* @param eps 边界判定容差。
|
|
74
|
+
* @returns 边界或区间外返回 `[]`;内部切分返回两段区间。
|
|
75
|
+
*/
|
|
76
|
+
split(u: number, eps?: number): PeriodInterval[];
|
|
77
|
+
/**
|
|
78
|
+
* 克隆当前周期区间。
|
|
79
|
+
* @returns 与当前数值等价的新实例。
|
|
80
|
+
*/
|
|
81
|
+
clone(): PeriodInterval;
|
|
82
|
+
/**
|
|
83
|
+
* 当前区间沿正方向长度。
|
|
84
|
+
* @returns `_end - _start`。
|
|
85
|
+
*/
|
|
86
|
+
private span;
|
|
87
|
+
/**
|
|
88
|
+
* 判断是否为整周期闭合区间。
|
|
89
|
+
* @param eps 比较容差。
|
|
90
|
+
* @returns 近似等于整周期长度时返回 `true`。
|
|
91
|
+
*/
|
|
92
|
+
private isFull;
|
|
93
|
+
/**
|
|
94
|
+
* 计算两参数在圆周上的最短距离。
|
|
95
|
+
* @param a 参数 a。
|
|
96
|
+
* @param b 参数 b。
|
|
97
|
+
* @returns 最短圆周距离。
|
|
98
|
+
*/
|
|
99
|
+
private circularDistance;
|
|
100
|
+
/**
|
|
101
|
+
* 计算从 `a` 到 `b` 的正方向差值。
|
|
102
|
+
* @param a 起点参数。
|
|
103
|
+
* @param b 终点参数。
|
|
104
|
+
* @returns 归一化到 `[0, period)` 的正向差值。
|
|
105
|
+
*/
|
|
106
|
+
private forwardDelta;
|
|
107
|
+
/**
|
|
108
|
+
* 转为 `[0, period]` 上的普通线性区间段。
|
|
109
|
+
* @param eps 判定整周期与边界贴合的容差。
|
|
110
|
+
* @returns 线性区间段数组。
|
|
111
|
+
*/
|
|
112
|
+
private toLinearSegments;
|
|
113
|
+
/**
|
|
114
|
+
* 规范化输入到内部表示。
|
|
115
|
+
* @param start 输入起点。
|
|
116
|
+
* @param end 输入终点。
|
|
117
|
+
* @param period 周期长度。
|
|
118
|
+
* @returns 规范化后的 `{ start, end }`,满足 `start in [0, period)` 且 `end = start + len`。
|
|
119
|
+
*/
|
|
120
|
+
private static canonicalize;
|
|
121
|
+
/**
|
|
122
|
+
* 正模运算。
|
|
123
|
+
* @param x 被取模值。
|
|
124
|
+
* @param m 模(周期)。
|
|
125
|
+
* @returns 结果范围在 `[0, m)`。
|
|
126
|
+
*/
|
|
127
|
+
private static mod;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=period_interval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"period_interval.d.ts","sourceRoot":"","sources":["../../src/curves/period_interval.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,qBAAa,cAAe,SAAQ,QAAQ;IACxC,kBAAkB;IAClB,SAAgB,MAAM,EAAE,MAAM,CAAA;IAE9B;;;;;OAKG;gBACS,KAAK,SAAI,EAAE,GAAG,SAAI,EAAE,MAAM,SAAc;IAQpD;;;;OAIG;IACI,SAAS,CAAC,CAAC,EAAE,MAAM;IAI1B;;;;;OAKG;IACI,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,SAAa;IAItD;;;;OAIG;IACI,KAAK,CAAC,MAAM,EAAE,MAAM;IAI3B;;;OAGG;IACa,MAAM;IAItB;;;;;OAKG;IACa,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAgB;IAMvD;;;;OAIG;IACa,KAAK,CAAC,CAAC,EAAE,MAAM;IAU/B;;;;;OAKG;IACa,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,SAAgB;IAOjE;;;;;OAKG;IACa,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,SAAgB,GAAG,cAAc,EAAE;IAcvF;;;;;OAKG;IACa,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,SAAgB,GAAG,cAAc,EAAE;IAqBnF;;;;;OAKG;IACa,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAgB,GAAG,cAAc,EAAE;IAavE;;;OAGG;IACa,KAAK;IAIrB;;;OAGG;IACH,OAAO,CAAC,IAAI;IAIZ;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAId;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAS3B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,GAAG;CAIrB"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Linea Math - Curves
|
|
3
|
+
* PeriodInterval: 周期参数区间
|
|
4
|
+
*/
|
|
5
|
+
import { MathError } from '../utils/math_error';
|
|
6
|
+
import { Precision } from '../utils/precision';
|
|
7
|
+
import { Interval } from './interval';
|
|
8
|
+
export class PeriodInterval extends Interval {
|
|
9
|
+
/**
|
|
10
|
+
* 创建周期区间。
|
|
11
|
+
* @param start 区间起点,可为任意实数。
|
|
12
|
+
* @param end 区间终点,可为任意实数。
|
|
13
|
+
* @param period 周期长度,必须大于 0。
|
|
14
|
+
*/
|
|
15
|
+
constructor(start = 0, end = 0, period = Math.PI * 2) {
|
|
16
|
+
MathError.assert(Number.isFinite(start) && Number.isFinite(end), 'PeriodInterval: start/end must be finite');
|
|
17
|
+
MathError.assert(period > 0, 'PeriodInterval: period must be > 0');
|
|
18
|
+
const canonical = PeriodInterval.canonicalize(start, end, period);
|
|
19
|
+
super(canonical.start, canonical.end);
|
|
20
|
+
this.period = period;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 将参数归一化到 `[0, period)`。
|
|
24
|
+
* @param u 待归一化参数。
|
|
25
|
+
* @returns 归一化后的参数值。
|
|
26
|
+
*/
|
|
27
|
+
normalize(u) {
|
|
28
|
+
return PeriodInterval.mod(u, this.period);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 将参数归一化到指定周期窗口 `[start, start + period)`。
|
|
32
|
+
* @param u 待归一化参数。
|
|
33
|
+
* @param start 周期窗口起点,默认当前区间起点。
|
|
34
|
+
* @returns 与 `u` 周期等价,且落在窗口内的参数。
|
|
35
|
+
*/
|
|
36
|
+
normalizeInPeriod(u, start = this.start) {
|
|
37
|
+
return start + PeriodInterval.mod(u - start, this.period);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 区间整体平移(按周期等价)。
|
|
41
|
+
* @param offset 平移量。
|
|
42
|
+
* @returns 平移后的新区间实例。
|
|
43
|
+
*/
|
|
44
|
+
shift(offset) {
|
|
45
|
+
return new PeriodInterval(this._start + offset, this._start + this.span() + offset, this.period);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 计算周期区间长度(沿正方向)。
|
|
49
|
+
* @returns 区间跨度,范围在 `[0, period]`。
|
|
50
|
+
*/
|
|
51
|
+
length() {
|
|
52
|
+
return this.span();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 判断参数是否落在周期区间内。
|
|
56
|
+
* @param u 待判断参数。
|
|
57
|
+
* @param eps 边界比较容差。
|
|
58
|
+
* @returns 落在区间内(含容差)返回 `true`。
|
|
59
|
+
*/
|
|
60
|
+
contains(u, eps = Precision.EPS) {
|
|
61
|
+
if (this.isFull(eps))
|
|
62
|
+
return true;
|
|
63
|
+
const d = this.forwardDelta(this._start, this.normalize(u));
|
|
64
|
+
return d <= this.span() + eps || this.period - d <= eps;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 将参数限制到区间内。
|
|
68
|
+
* @param u 输入参数。
|
|
69
|
+
* @returns 已在区间内返回归一化参数;否则返回最近边界参数。
|
|
70
|
+
*/
|
|
71
|
+
clamp(u) {
|
|
72
|
+
const t = this.normalize(u);
|
|
73
|
+
if (this.contains(t))
|
|
74
|
+
return t;
|
|
75
|
+
const end = this.normalize(this._start + this.span());
|
|
76
|
+
const dStart = this.circularDistance(t, this._start);
|
|
77
|
+
const dEnd = this.circularDistance(t, end);
|
|
78
|
+
return dStart <= dEnd ? this._start : end;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 判断两个周期区间是否近似相等。
|
|
82
|
+
* @param other 对比区间。
|
|
83
|
+
* @param eps 数值比较容差。
|
|
84
|
+
* @returns 周期一致且区间位置/长度一致时返回 `true`。
|
|
85
|
+
*/
|
|
86
|
+
equals(other, eps = Precision.EPS) {
|
|
87
|
+
if (!Precision.equal(this.period, other.period, eps))
|
|
88
|
+
return false;
|
|
89
|
+
if (this.isFull(eps) && other.isFull(eps))
|
|
90
|
+
return true;
|
|
91
|
+
return Precision.equal(this._start, other._start, eps) &&
|
|
92
|
+
Precision.equal(this.span(), other.span(), eps);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 计算周期交集。
|
|
96
|
+
* @param other 参与求交的周期区间。
|
|
97
|
+
* @param eps 交并判定容差。
|
|
98
|
+
* @returns 交集结果,按线性分段返回 `PeriodInterval[]`(最多 2 段)。
|
|
99
|
+
*/
|
|
100
|
+
intersect(other, eps = Precision.EPS) {
|
|
101
|
+
if (!Precision.equal(this.period, other.period, eps)) {
|
|
102
|
+
MathError.throw('PeriodInterval.intersect: period mismatch');
|
|
103
|
+
}
|
|
104
|
+
const ret = [];
|
|
105
|
+
for (const a of this.toLinearSegments(eps)) {
|
|
106
|
+
for (const b of other.toLinearSegments(eps)) {
|
|
107
|
+
ret.push(...a.intersect(b, eps));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return Interval.merge(ret, eps).map((seg) => new PeriodInterval(seg.start, seg.end, this.period));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 计算周期并集。
|
|
114
|
+
* @param other 参与求并的周期区间。
|
|
115
|
+
* @param eps 交并判定容差。
|
|
116
|
+
* @returns 并集结果,按线性分段返回 `PeriodInterval[]`(1 到 2 段)。
|
|
117
|
+
*/
|
|
118
|
+
union(other, eps = Precision.EPS) {
|
|
119
|
+
if (!Precision.equal(this.period, other.period, eps)) {
|
|
120
|
+
MathError.throw('PeriodInterval.union: period mismatch');
|
|
121
|
+
}
|
|
122
|
+
const merged = Interval.merge([
|
|
123
|
+
...this.toLinearSegments(eps),
|
|
124
|
+
...other.toLinearSegments(eps),
|
|
125
|
+
], eps);
|
|
126
|
+
if (merged.length >= 2) {
|
|
127
|
+
const first = merged[0];
|
|
128
|
+
const last = merged[merged.length - 1];
|
|
129
|
+
if (Precision.equal(first.start, 0, eps) && Precision.equal(last.end, this.period, eps)) {
|
|
130
|
+
const stitched = new Interval(last.start, this.period + first.end);
|
|
131
|
+
return [stitched, ...merged.slice(1, -1)].map((seg) => new PeriodInterval(seg.start, seg.end, this.period));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return merged.map((seg) => new PeriodInterval(seg.start, seg.end, this.period));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 以参数 `u` 对周期区间切分。
|
|
138
|
+
* @param u 切分参数。
|
|
139
|
+
* @param eps 边界判定容差。
|
|
140
|
+
* @returns 边界或区间外返回 `[]`;内部切分返回两段区间。
|
|
141
|
+
*/
|
|
142
|
+
split(u, eps = Precision.EPS) {
|
|
143
|
+
if (!this.contains(u, eps))
|
|
144
|
+
return [];
|
|
145
|
+
const d = this.forwardDelta(this._start, this.normalize(u));
|
|
146
|
+
const len = this.span();
|
|
147
|
+
if (d <= eps || d >= len - eps)
|
|
148
|
+
return [];
|
|
149
|
+
const mid = this._start + d;
|
|
150
|
+
return [
|
|
151
|
+
new PeriodInterval(this._start, mid, this.period),
|
|
152
|
+
new PeriodInterval(mid, this._start + len, this.period),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 克隆当前周期区间。
|
|
157
|
+
* @returns 与当前数值等价的新实例。
|
|
158
|
+
*/
|
|
159
|
+
clone() {
|
|
160
|
+
return new PeriodInterval(this._start, this._start + this.span(), this.period);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 当前区间沿正方向长度。
|
|
164
|
+
* @returns `_end - _start`。
|
|
165
|
+
*/
|
|
166
|
+
span() {
|
|
167
|
+
return this._end - this._start;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 判断是否为整周期闭合区间。
|
|
171
|
+
* @param eps 比较容差。
|
|
172
|
+
* @returns 近似等于整周期长度时返回 `true`。
|
|
173
|
+
*/
|
|
174
|
+
isFull(eps = Precision.EPS) {
|
|
175
|
+
return Precision.equal(this.span(), this.period, eps);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 计算两参数在圆周上的最短距离。
|
|
179
|
+
* @param a 参数 a。
|
|
180
|
+
* @param b 参数 b。
|
|
181
|
+
* @returns 最短圆周距离。
|
|
182
|
+
*/
|
|
183
|
+
circularDistance(a, b) {
|
|
184
|
+
const d = Math.abs(a - b);
|
|
185
|
+
return Math.min(d, this.period - d);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* 计算从 `a` 到 `b` 的正方向差值。
|
|
189
|
+
* @param a 起点参数。
|
|
190
|
+
* @param b 终点参数。
|
|
191
|
+
* @returns 归一化到 `[0, period)` 的正向差值。
|
|
192
|
+
*/
|
|
193
|
+
forwardDelta(a, b) {
|
|
194
|
+
return PeriodInterval.mod(b - a, this.period);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 转为 `[0, period]` 上的普通线性区间段。
|
|
198
|
+
* @param eps 判定整周期与边界贴合的容差。
|
|
199
|
+
* @returns 线性区间段数组。
|
|
200
|
+
*/
|
|
201
|
+
toLinearSegments(eps = Precision.EPS) {
|
|
202
|
+
if (this.isFull(eps)) {
|
|
203
|
+
return [new Interval(0, this.period)];
|
|
204
|
+
}
|
|
205
|
+
const s = this._start;
|
|
206
|
+
const e = this._start + this.span();
|
|
207
|
+
if (e <= this.period + eps) {
|
|
208
|
+
return [new Interval(s, Math.min(e, this.period))];
|
|
209
|
+
}
|
|
210
|
+
return [
|
|
211
|
+
new Interval(s, this.period),
|
|
212
|
+
new Interval(0, e - this.period),
|
|
213
|
+
];
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 规范化输入到内部表示。
|
|
217
|
+
* @param start 输入起点。
|
|
218
|
+
* @param end 输入终点。
|
|
219
|
+
* @param period 周期长度。
|
|
220
|
+
* @returns 规范化后的 `{ start, end }`,满足 `start in [0, period)` 且 `end = start + len`。
|
|
221
|
+
*/
|
|
222
|
+
static canonicalize(start, end, period) {
|
|
223
|
+
const s = PeriodInterval.mod(start, period);
|
|
224
|
+
let len = PeriodInterval.mod(end - start, period);
|
|
225
|
+
if (Precision.equal(len, 0, Precision.EPS) && !Precision.equal(start, end, Precision.EPS)) {
|
|
226
|
+
len = period;
|
|
227
|
+
}
|
|
228
|
+
return { start: s, end: s + len };
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* 正模运算。
|
|
232
|
+
* @param x 被取模值。
|
|
233
|
+
* @param m 模(周期)。
|
|
234
|
+
* @returns 结果范围在 `[0, m)`。
|
|
235
|
+
*/
|
|
236
|
+
static mod(x, m) {
|
|
237
|
+
const r = x % m;
|
|
238
|
+
return r < 0 ? r + m : r;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const DISCRETIZE_DEFAULTS: Readonly<{
|
|
2
|
+
chordTol: 0.001;
|
|
3
|
+
angleTolRad: number;
|
|
4
|
+
maxSegmentLength: number;
|
|
5
|
+
minSegments: 8;
|
|
6
|
+
maxSegments: 4096;
|
|
7
|
+
includeEnd: true;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const DISCRETIZE_INTERNAL_DEFAULTS: Readonly<{
|
|
10
|
+
minSegmentLengthInternal: number;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=discretize_defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discretize_defaults.d.ts","sourceRoot":"","sources":["../../src/discretize/discretize_defaults.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB;;;;;;;EAO9B,CAAA;AAEF,eAAO,MAAM,4BAA4B;;EAEvC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Precision } from '../utils/precision';
|
|
2
|
+
export const DISCRETIZE_DEFAULTS = Object.freeze({
|
|
3
|
+
chordTol: 1e-3,
|
|
4
|
+
angleTolRad: Math.PI / 180,
|
|
5
|
+
maxSegmentLength: Number.POSITIVE_INFINITY,
|
|
6
|
+
minSegments: 8,
|
|
7
|
+
maxSegments: 4096,
|
|
8
|
+
includeEnd: true,
|
|
9
|
+
});
|
|
10
|
+
export const DISCRETIZE_INTERNAL_DEFAULTS = Object.freeze({
|
|
11
|
+
minSegmentLengthInternal: Precision.CURVE_LENGTH_EPS,
|
|
12
|
+
});
|