likec4 1.59.3 → 1.60.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/__app__/codegen/react.mjs +6 -6
- package/__app__/codegen/webcomponent.mjs +147 -69
- package/__app__/src/aichat/index.mjs +10 -5
- package/__app__/src/chunks/AIChat.mjs +1134 -693
- package/__app__/src/chunks/LikeC4Styles.mjs +4101 -1737
- package/__app__/src/chunks/ProjectsOverview.mjs +624 -334
- package/__app__/src/chunks/es.mjs +515 -335
- package/__app__/src/chunks/hooks.mjs +578 -366
- package/__app__/src/chunks/libs/@floating-ui.mjs +2720 -1966
- package/__app__/src/chunks/libs/@mantine.mjs +14067 -9487
- package/__app__/src/chunks/libs/@tanstack-ai.mjs +2266 -1146
- package/__app__/src/chunks/libs/@tanstack.mjs +3152 -1932
- package/__app__/src/chunks/libs/@xstate/react.mjs +2924 -1468
- package/__app__/src/chunks/libs/@xyflow/react.mjs +6627 -4067
- package/__app__/src/chunks/libs/bezier-js.mjs +1312 -726
- package/__app__/src/chunks/libs/d3.mjs +3218 -1509
- package/__app__/src/chunks/libs/fast-equals.mjs +437 -201
- package/__app__/src/chunks/libs/framer.mjs +9251 -3846
- package/__app__/src/chunks/libs/nanostores.mjs +174 -0
- package/__app__/src/chunks/libs/zod.mjs +4591 -2363
- package/__app__/src/chunks/rolldown-runtime.mjs +39 -23
- package/__app__/src/chunks/styled-system.mjs +3538 -756
- package/__app__/src/fonts.css +112 -1
- package/__app__/src/main.mjs +44398 -24039
- package/__app__/src/style.css +18488 -1
- package/config/schema.json +136 -97
- package/dist/app/render-view-client.css +1 -1
- package/dist/app/render-view-client.js +506 -338
- package/dist/chunks/enableServer.mjs +1 -1
- package/dist/chunks/filenames.mjs +16 -14
- package/dist/chunks/generate-likec4.mjs +5 -0
- package/dist/chunks/index.d.mts +246 -180
- package/dist/chunks/index2.d.mts +2882 -1977
- package/dist/chunks/libs/@chevrotain/gast.mjs +27 -1
- package/dist/chunks/libs/@chevrotain/regexp-to-ast.mjs +81 -9
- package/dist/chunks/libs/@chevrotain/types.d.mts +111 -0
- package/dist/chunks/libs/@logtape/logtape.mjs +5 -4
- package/dist/chunks/libs/@lume/kiwi.mjs +1 -1
- package/dist/chunks/libs/@ts-graphviz/core.mjs +1 -1
- package/dist/chunks/libs/birpc.mjs +1 -1
- package/dist/chunks/libs/chevrotain-allstar.mjs +2 -2
- package/dist/chunks/libs/chevrotain.mjs +87 -35
- package/dist/chunks/libs/eventemitter3.mjs +1 -1
- package/dist/chunks/libs/json5.mjs +4 -4
- package/dist/chunks/libs/langium.d.mts +9903 -5297
- package/dist/chunks/libs/langium.mjs +16 -24
- package/dist/chunks/libs/merge-error-cause.mjs +1 -1
- package/dist/chunks/libs/p-limit.mjs +1 -0
- package/dist/chunks/libs/p-queue.mjs +1 -1
- package/dist/chunks/libs/package-manager-detector.mjs +1 -1
- package/dist/chunks/libs/pako.mjs +2 -2
- package/dist/chunks/libs/pretty-ms.mjs +1 -1
- package/dist/chunks/libs/remeda.mjs +1 -1
- package/dist/chunks/libs/ufo.mjs +1 -1
- package/dist/chunks/libs/unstorage.mjs +1 -1
- package/dist/chunks/libs/which.mjs +1 -1
- package/dist/chunks/node.mjs +60 -60
- package/dist/chunks/rolldown-runtime.mjs +1 -1
- package/dist/chunks/sequence-view.mjs +1 -1
- package/dist/chunks/vite-plugin.mjs +55 -52
- package/dist/cli/index.d.mts +1 -1
- package/dist/cli/index.mjs +208 -1300
- package/dist/config/index.d.mts +2 -2
- package/dist/generators/likec4.d.mts +6578 -0
- package/dist/generators/likec4.mjs +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/model/index.d.mts +8 -5
- package/dist/vite-plugin/index.d.mts +6 -3
- package/dist/vite-plugin/index.mjs +1 -1
- package/dist/vite-plugin/internal/chunks/rolldown-runtime.mjs +9 -0
- package/dist/vite-plugin/internal/index.d.mts +16 -15
- package/dist/vite-plugin/internal/index.mjs +144 -46
- package/generators/likec4/package.json +4 -0
- package/package.json +117 -110
- package/react/index.d.mts +8500 -5399
- package/react/index.mjs +534 -58617
- package/react/rolldown-runtime-DnkiqaRY.js +1 -0
- package/skills/likec4-dsl/SKILL.md +428 -0
- package/skills/likec4-dsl/evals/evals-public.json +202 -0
- package/skills/likec4-dsl/evals/grading-spec.json +589 -0
- package/skills/likec4-dsl/references/bridge-leanix-drawio.md +42 -0
- package/skills/likec4-dsl/references/cli.md +139 -0
- package/skills/likec4-dsl/references/configuration.md +266 -0
- package/skills/likec4-dsl/references/deployment.md +160 -0
- package/skills/likec4-dsl/references/dynamic-views.md +455 -0
- package/skills/likec4-dsl/references/examples.md +370 -0
- package/skills/likec4-dsl/references/identifier-validity.md +90 -0
- package/skills/likec4-dsl/references/include-predicates-wildcards.md +179 -0
- package/skills/likec4-dsl/references/model.md +151 -0
- package/skills/likec4-dsl/references/predicates.md +123 -0
- package/skills/likec4-dsl/references/relationships-bidirectional.md +176 -0
- package/skills/likec4-dsl/references/specification.md +75 -0
- package/skills/likec4-dsl/references/style-tokens-colors.md +150 -0
- package/skills/likec4-dsl/references/troubleshooting.md +96 -0
- package/skills/likec4-dsl/references/views.md +329 -0
- package/vite-plugin-modules.d.ts +4 -2
- package/dist/chunks/libs/picomatch.mjs +0 -1
- package/dist/chunks/libs/zod.d.mts +0 -2140
- package/dist/chunks/libs/zod.mjs +0 -65
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import "../rolldown-runtime.mjs";
|
|
2
2
|
//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/utils.js
|
|
3
|
-
var { abs:
|
|
4
|
-
function crt(
|
|
5
|
-
return
|
|
3
|
+
var { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
|
|
4
|
+
function crt(v) {
|
|
5
|
+
return v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);
|
|
6
6
|
}
|
|
7
|
-
var
|
|
7
|
+
var pi$1 = Math.PI;
|
|
8
|
+
var tau = 2 * pi$1;
|
|
9
|
+
var quart = pi$1 / 2;
|
|
10
|
+
var epsilon = 1e-6;
|
|
11
|
+
var nMax = Number.MAX_SAFE_INTEGER || 9007199254740991;
|
|
12
|
+
var nMin = Number.MIN_SAFE_INTEGER || -9007199254740991;
|
|
13
|
+
var ZERO = {
|
|
8
14
|
x: 0,
|
|
9
15
|
y: 0,
|
|
10
16
|
z: 0
|
|
11
|
-
}
|
|
17
|
+
};
|
|
18
|
+
var utils = {
|
|
12
19
|
Tvalues: [
|
|
13
20
|
-.06405689286260563,
|
|
14
21
|
.06405689286260563,
|
|
@@ -61,250 +68,376 @@ var c = Math.PI, l = 2 * c, u = c / 2, f = 1e-6, p = 2 ** 53 - 1 || 900719925474
|
|
|
61
68
|
.0123412297999872,
|
|
62
69
|
.0123412297999872
|
|
63
70
|
],
|
|
64
|
-
arcfn: function(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
arcfn: function(t, derivativeFn) {
|
|
72
|
+
const d = derivativeFn(t);
|
|
73
|
+
let l = d.x * d.x + d.y * d.y;
|
|
74
|
+
if (typeof d.z !== "undefined") l += d.z * d.z;
|
|
75
|
+
return sqrt$1(l);
|
|
76
|
+
},
|
|
77
|
+
compute: function(t, points, _3d) {
|
|
78
|
+
if (t === 0) {
|
|
79
|
+
points[0].t = 0;
|
|
80
|
+
return points[0];
|
|
81
|
+
}
|
|
82
|
+
const order = points.length - 1;
|
|
83
|
+
if (t === 1) {
|
|
84
|
+
points[order].t = 1;
|
|
85
|
+
return points[order];
|
|
86
|
+
}
|
|
87
|
+
const mt = 1 - t;
|
|
88
|
+
let p = points;
|
|
89
|
+
if (order === 0) {
|
|
90
|
+
points[0].t = t;
|
|
91
|
+
return points[0];
|
|
92
|
+
}
|
|
93
|
+
if (order === 1) {
|
|
94
|
+
const ret = {
|
|
95
|
+
x: mt * p[0].x + t * p[1].x,
|
|
96
|
+
y: mt * p[0].y + t * p[1].y,
|
|
97
|
+
t
|
|
79
98
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
if (_3d) ret.z = mt * p[0].z + t * p[1].z;
|
|
100
|
+
return ret;
|
|
101
|
+
}
|
|
102
|
+
if (order < 4) {
|
|
103
|
+
let mt2 = mt * mt;
|
|
104
|
+
let t2 = t * t;
|
|
105
|
+
let a;
|
|
106
|
+
let b;
|
|
107
|
+
let c;
|
|
108
|
+
let d = 0;
|
|
109
|
+
if (order === 2) {
|
|
110
|
+
p = [
|
|
111
|
+
p[0],
|
|
112
|
+
p[1],
|
|
113
|
+
p[2],
|
|
114
|
+
ZERO
|
|
115
|
+
];
|
|
116
|
+
a = mt2;
|
|
117
|
+
b = mt * t * 2;
|
|
118
|
+
c = t2;
|
|
119
|
+
} else if (order === 3) {
|
|
120
|
+
a = mt2 * mt;
|
|
121
|
+
b = mt2 * t * 3;
|
|
122
|
+
c = mt * t2 * 3;
|
|
123
|
+
d = t * t2;
|
|
124
|
+
}
|
|
125
|
+
const ret = {
|
|
126
|
+
x: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,
|
|
127
|
+
y: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,
|
|
128
|
+
t
|
|
94
129
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
if (_3d) ret.z = a * p[0].z + b * p[1].z + c * p[2].z + d * p[3].z;
|
|
131
|
+
return ret;
|
|
132
|
+
}
|
|
133
|
+
const dCpts = JSON.parse(JSON.stringify(points));
|
|
134
|
+
while (dCpts.length > 1) {
|
|
135
|
+
for (let i = 0; i < dCpts.length - 1; i++) {
|
|
136
|
+
dCpts[i] = {
|
|
137
|
+
x: dCpts[i].x + (dCpts[i + 1].x - dCpts[i].x) * t,
|
|
138
|
+
y: dCpts[i].y + (dCpts[i + 1].y - dCpts[i].y) * t
|
|
139
|
+
};
|
|
140
|
+
if (typeof dCpts[i].z !== "undefined") dCpts[i].z = dCpts[i].z + (dCpts[i + 1].z - dCpts[i].z) * t;
|
|
141
|
+
}
|
|
142
|
+
dCpts.splice(dCpts.length - 1, 1);
|
|
143
|
+
}
|
|
144
|
+
dCpts[0].t = t;
|
|
145
|
+
return dCpts[0];
|
|
146
|
+
},
|
|
147
|
+
computeWithRatios: function(t, points, ratios, _3d) {
|
|
148
|
+
const mt = 1 - t;
|
|
149
|
+
const r = ratios;
|
|
150
|
+
const p = points;
|
|
151
|
+
let f1 = r[0];
|
|
152
|
+
let f2 = r[1];
|
|
153
|
+
let f3 = r[2];
|
|
154
|
+
let f4 = r[3];
|
|
155
|
+
let d;
|
|
156
|
+
f1 *= mt;
|
|
157
|
+
f2 *= t;
|
|
158
|
+
if (p.length === 2) {
|
|
159
|
+
d = f1 + f2;
|
|
160
|
+
return {
|
|
161
|
+
x: (f1 * p[0].x + f2 * p[1].x) / d,
|
|
162
|
+
y: (f1 * p[0].y + f2 * p[1].y) / d,
|
|
163
|
+
z: !_3d ? false : (f1 * p[0].z + f2 * p[1].z) / d,
|
|
164
|
+
t
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
f1 *= mt;
|
|
168
|
+
f2 *= 2 * mt;
|
|
169
|
+
f3 *= t * t;
|
|
170
|
+
if (p.length === 3) {
|
|
171
|
+
d = f1 + f2 + f3;
|
|
172
|
+
return {
|
|
173
|
+
x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x) / d,
|
|
174
|
+
y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y) / d,
|
|
175
|
+
z: !_3d ? false : (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z) / d,
|
|
176
|
+
t
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
f1 *= mt;
|
|
180
|
+
f2 *= 1.5 * mt;
|
|
181
|
+
f3 *= 3 * mt;
|
|
182
|
+
f4 *= t * t * t;
|
|
183
|
+
if (p.length === 4) {
|
|
184
|
+
d = f1 + f2 + f3 + f4;
|
|
185
|
+
return {
|
|
186
|
+
x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x + f4 * p[3].x) / d,
|
|
187
|
+
y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y + f4 * p[3].y) / d,
|
|
188
|
+
z: !_3d ? false : (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z + f4 * p[3].z) / d,
|
|
189
|
+
t
|
|
190
|
+
};
|
|
191
|
+
}
|
|
127
192
|
},
|
|
128
|
-
derive: function(
|
|
129
|
-
|
|
130
|
-
for (let
|
|
131
|
-
|
|
132
|
-
for (let
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
derive: function(points, _3d) {
|
|
194
|
+
const dpoints = [];
|
|
195
|
+
for (let p = points, d = p.length, c = d - 1; d > 1; d--, c--) {
|
|
196
|
+
const list = [];
|
|
197
|
+
for (let j = 0, dpt; j < c; j++) {
|
|
198
|
+
dpt = {
|
|
199
|
+
x: c * (p[j + 1].x - p[j].x),
|
|
200
|
+
y: c * (p[j + 1].y - p[j].y)
|
|
201
|
+
};
|
|
202
|
+
if (_3d) dpt.z = c * (p[j + 1].z - p[j].z);
|
|
203
|
+
list.push(dpt);
|
|
204
|
+
}
|
|
205
|
+
dpoints.push(list);
|
|
206
|
+
p = list;
|
|
207
|
+
}
|
|
208
|
+
return dpoints;
|
|
209
|
+
},
|
|
210
|
+
between: function(v, m, M) {
|
|
211
|
+
return m <= v && v <= M || utils.approximately(v, m) || utils.approximately(v, M);
|
|
212
|
+
},
|
|
213
|
+
approximately: function(a, b, precision) {
|
|
214
|
+
return abs$1(a - b) <= (precision || epsilon);
|
|
215
|
+
},
|
|
216
|
+
length: function(derivativeFn) {
|
|
217
|
+
const z = .5;
|
|
218
|
+
const len = utils.Tvalues.length;
|
|
219
|
+
let sum = 0;
|
|
220
|
+
for (let i = 0, t; i < len; i++) {
|
|
221
|
+
t = z * utils.Tvalues[i] + z;
|
|
222
|
+
sum += utils.Cvalues[i] * utils.arcfn(t, derivativeFn);
|
|
223
|
+
}
|
|
224
|
+
return z * sum;
|
|
225
|
+
},
|
|
226
|
+
map: function(v, ds, de, ts, te) {
|
|
227
|
+
const d1 = de - ds;
|
|
228
|
+
return ts + (te - ts) * ((v - ds) / d1);
|
|
229
|
+
},
|
|
230
|
+
lerp: function(r, v1, v2) {
|
|
231
|
+
const ret = {
|
|
232
|
+
x: v1.x + r * (v2.x - v1.x),
|
|
233
|
+
y: v1.y + r * (v2.y - v1.y)
|
|
159
234
|
};
|
|
160
|
-
|
|
235
|
+
if (v1.z !== void 0 && v2.z !== void 0) ret.z = v1.z + r * (v2.z - v1.z);
|
|
236
|
+
return ret;
|
|
161
237
|
},
|
|
162
|
-
pointToString: function(
|
|
163
|
-
let
|
|
164
|
-
|
|
238
|
+
pointToString: function(p) {
|
|
239
|
+
let s = p.x + "/" + p.y;
|
|
240
|
+
if (typeof p.z !== "undefined") s += "/" + p.z;
|
|
241
|
+
return s;
|
|
165
242
|
},
|
|
166
|
-
pointsToString: function(
|
|
167
|
-
return "[" +
|
|
243
|
+
pointsToString: function(points) {
|
|
244
|
+
return "[" + points.map(utils.pointToString).join(", ") + "]";
|
|
168
245
|
},
|
|
169
|
-
copy: function(
|
|
170
|
-
return JSON.parse(JSON.stringify(
|
|
246
|
+
copy: function(obj) {
|
|
247
|
+
return JSON.parse(JSON.stringify(obj));
|
|
171
248
|
},
|
|
172
|
-
angle: function(
|
|
173
|
-
|
|
174
|
-
|
|
249
|
+
angle: function(o, v1, v2) {
|
|
250
|
+
const dx1 = v1.x - o.x;
|
|
251
|
+
const dy1 = v1.y - o.y;
|
|
252
|
+
const dx2 = v2.x - o.x;
|
|
253
|
+
const dy2 = v2.y - o.y;
|
|
254
|
+
return atan2(dx1 * dy2 - dy1 * dx2, dx1 * dx2 + dy1 * dy2);
|
|
175
255
|
},
|
|
176
|
-
round: function(
|
|
177
|
-
|
|
178
|
-
|
|
256
|
+
round: function(v, d) {
|
|
257
|
+
const s = "" + v;
|
|
258
|
+
const pos = s.indexOf(".");
|
|
259
|
+
return parseFloat(s.substring(0, pos + 1 + d));
|
|
179
260
|
},
|
|
180
|
-
dist: function(
|
|
181
|
-
|
|
182
|
-
|
|
261
|
+
dist: function(p1, p2) {
|
|
262
|
+
const dx = p1.x - p2.x;
|
|
263
|
+
const dy = p1.y - p2.y;
|
|
264
|
+
return sqrt$1(dx * dx + dy * dy);
|
|
183
265
|
},
|
|
184
|
-
closest: function(
|
|
185
|
-
let
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
266
|
+
closest: function(LUT, point) {
|
|
267
|
+
let mdist = pow(2, 63);
|
|
268
|
+
let mpos;
|
|
269
|
+
let d;
|
|
270
|
+
LUT.forEach(function(p, idx) {
|
|
271
|
+
d = utils.dist(point, p);
|
|
272
|
+
if (d < mdist) {
|
|
273
|
+
mdist = d;
|
|
274
|
+
mpos = idx;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
return {
|
|
278
|
+
mdist,
|
|
279
|
+
mpos
|
|
191
280
|
};
|
|
192
281
|
},
|
|
193
|
-
abcratio: function(
|
|
194
|
-
if (
|
|
195
|
-
if (
|
|
196
|
-
else if (
|
|
197
|
-
|
|
198
|
-
return
|
|
199
|
-
},
|
|
200
|
-
projectionratio: function(
|
|
201
|
-
if (n !== 2 && n !== 3) return
|
|
202
|
-
if (
|
|
203
|
-
else if (
|
|
204
|
-
|
|
205
|
-
return
|
|
206
|
-
},
|
|
207
|
-
lli8: function(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
282
|
+
abcratio: function(t, n) {
|
|
283
|
+
if (n !== 2 && n !== 3) return false;
|
|
284
|
+
if (typeof t === "undefined") t = .5;
|
|
285
|
+
else if (t === 0 || t === 1) return t;
|
|
286
|
+
const bottom = pow(t, n) + pow(1 - t, n);
|
|
287
|
+
return abs$1((bottom - 1) / bottom);
|
|
288
|
+
},
|
|
289
|
+
projectionratio: function(t, n) {
|
|
290
|
+
if (n !== 2 && n !== 3) return false;
|
|
291
|
+
if (typeof t === "undefined") t = .5;
|
|
292
|
+
else if (t === 0 || t === 1) return t;
|
|
293
|
+
const top = pow(1 - t, n);
|
|
294
|
+
return top / (pow(t, n) + top);
|
|
295
|
+
},
|
|
296
|
+
lli8: function(x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
297
|
+
const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
|
|
298
|
+
const ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
|
|
299
|
+
const d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
|
300
|
+
if (d == 0) return false;
|
|
301
|
+
return {
|
|
302
|
+
x: nx / d,
|
|
303
|
+
y: ny / d
|
|
212
304
|
};
|
|
213
305
|
},
|
|
214
|
-
lli4: function(
|
|
215
|
-
|
|
216
|
-
|
|
306
|
+
lli4: function(p1, p2, p3, p4) {
|
|
307
|
+
const x1 = p1.x;
|
|
308
|
+
const y1 = p1.y;
|
|
309
|
+
const x2 = p2.x;
|
|
310
|
+
const y2 = p2.y;
|
|
311
|
+
const x3 = p3.x;
|
|
312
|
+
const y3 = p3.y;
|
|
313
|
+
const x4 = p4.x;
|
|
314
|
+
const y4 = p4.y;
|
|
315
|
+
return utils.lli8(x1, y1, x2, y2, x3, y3, x4, y4);
|
|
217
316
|
},
|
|
218
|
-
lli: function(
|
|
219
|
-
return
|
|
317
|
+
lli: function(v1, v2) {
|
|
318
|
+
return utils.lli4(v1, v1.c, v2, v2.c);
|
|
220
319
|
},
|
|
221
|
-
makeline: function(
|
|
222
|
-
return new
|
|
320
|
+
makeline: function(p1, p2) {
|
|
321
|
+
return new Bezier(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, p2.x, p2.y);
|
|
223
322
|
},
|
|
224
|
-
findbbox: function(
|
|
225
|
-
let
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
323
|
+
findbbox: function(sections) {
|
|
324
|
+
let mx = nMax;
|
|
325
|
+
let my = nMax;
|
|
326
|
+
let MX = nMin;
|
|
327
|
+
let MY = nMin;
|
|
328
|
+
sections.forEach(function(s) {
|
|
329
|
+
const bbox = s.bbox();
|
|
330
|
+
if (mx > bbox.x.min) mx = bbox.x.min;
|
|
331
|
+
if (my > bbox.y.min) my = bbox.y.min;
|
|
332
|
+
if (MX < bbox.x.max) MX = bbox.x.max;
|
|
333
|
+
if (MY < bbox.y.max) MY = bbox.y.max;
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
230
336
|
x: {
|
|
231
|
-
min:
|
|
232
|
-
mid: (
|
|
233
|
-
max:
|
|
234
|
-
size:
|
|
337
|
+
min: mx,
|
|
338
|
+
mid: (mx + MX) / 2,
|
|
339
|
+
max: MX,
|
|
340
|
+
size: MX - mx
|
|
235
341
|
},
|
|
236
342
|
y: {
|
|
237
|
-
min:
|
|
238
|
-
mid: (
|
|
239
|
-
max:
|
|
240
|
-
size:
|
|
343
|
+
min: my,
|
|
344
|
+
mid: (my + MY) / 2,
|
|
345
|
+
max: MY,
|
|
346
|
+
size: MY - my
|
|
241
347
|
}
|
|
242
348
|
};
|
|
243
349
|
},
|
|
244
|
-
shapeintersections: function(
|
|
245
|
-
if (!
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
r.startcap,
|
|
253
|
-
r.forward,
|
|
254
|
-
r.back,
|
|
255
|
-
r.endcap
|
|
350
|
+
shapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) {
|
|
351
|
+
if (!utils.bboxoverlap(bbox1, bbox2)) return [];
|
|
352
|
+
const intersections = [];
|
|
353
|
+
const a1 = [
|
|
354
|
+
s1.startcap,
|
|
355
|
+
s1.forward,
|
|
356
|
+
s1.back,
|
|
357
|
+
s1.endcap
|
|
256
358
|
];
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
359
|
+
const a2 = [
|
|
360
|
+
s2.startcap,
|
|
361
|
+
s2.forward,
|
|
362
|
+
s2.back,
|
|
363
|
+
s2.endcap
|
|
364
|
+
];
|
|
365
|
+
a1.forEach(function(l1) {
|
|
366
|
+
if (l1.virtual) return;
|
|
367
|
+
a2.forEach(function(l2) {
|
|
368
|
+
if (l2.virtual) return;
|
|
369
|
+
const iss = l1.intersects(l2, curveIntersectionThreshold);
|
|
370
|
+
if (iss.length > 0) {
|
|
371
|
+
iss.c1 = l1;
|
|
372
|
+
iss.c2 = l2;
|
|
373
|
+
iss.s1 = s1;
|
|
374
|
+
iss.s2 = s2;
|
|
375
|
+
intersections.push(iss);
|
|
376
|
+
}
|
|
262
377
|
});
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
378
|
+
});
|
|
379
|
+
return intersections;
|
|
380
|
+
},
|
|
381
|
+
makeshape: function(forward, back, curveIntersectionThreshold) {
|
|
382
|
+
const bpl = back.points.length;
|
|
383
|
+
const fpl = forward.points.length;
|
|
384
|
+
const start = utils.makeline(back.points[bpl - 1], forward.points[0]);
|
|
385
|
+
const end = utils.makeline(forward.points[fpl - 1], back.points[0]);
|
|
386
|
+
const shape = {
|
|
387
|
+
startcap: start,
|
|
388
|
+
forward,
|
|
389
|
+
back,
|
|
390
|
+
endcap: end,
|
|
391
|
+
bbox: utils.findbbox([
|
|
392
|
+
start,
|
|
393
|
+
forward,
|
|
394
|
+
back,
|
|
395
|
+
end
|
|
276
396
|
])
|
|
277
397
|
};
|
|
278
|
-
|
|
279
|
-
return
|
|
280
|
-
}
|
|
398
|
+
shape.intersections = function(s2) {
|
|
399
|
+
return utils.shapeintersections(shape, shape.bbox, s2, s2.bbox, curveIntersectionThreshold);
|
|
400
|
+
};
|
|
401
|
+
return shape;
|
|
281
402
|
},
|
|
282
|
-
getminmax: function(
|
|
283
|
-
if (!
|
|
403
|
+
getminmax: function(curve, d, list) {
|
|
404
|
+
if (!list) return {
|
|
284
405
|
min: 0,
|
|
285
406
|
max: 0
|
|
286
407
|
};
|
|
287
|
-
let
|
|
288
|
-
|
|
289
|
-
|
|
408
|
+
let min = nMax;
|
|
409
|
+
let max = nMin;
|
|
410
|
+
let t;
|
|
411
|
+
let c;
|
|
412
|
+
if (list.indexOf(0) === -1) list = [0].concat(list);
|
|
413
|
+
if (list.indexOf(1) === -1) list.push(1);
|
|
414
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
415
|
+
t = list[i];
|
|
416
|
+
c = curve.get(t);
|
|
417
|
+
if (c[d] < min) min = c[d];
|
|
418
|
+
if (c[d] > max) max = c[d];
|
|
419
|
+
}
|
|
290
420
|
return {
|
|
291
|
-
min
|
|
292
|
-
mid: (
|
|
293
|
-
max
|
|
294
|
-
size:
|
|
421
|
+
min,
|
|
422
|
+
mid: (min + max) / 2,
|
|
423
|
+
max,
|
|
424
|
+
size: max - min
|
|
295
425
|
};
|
|
296
426
|
},
|
|
297
|
-
align: function(
|
|
298
|
-
|
|
427
|
+
align: function(points, line) {
|
|
428
|
+
const tx = line.p1.x;
|
|
429
|
+
const ty = line.p1.y;
|
|
430
|
+
const a = -atan2(line.p2.y - ty, line.p2.x - tx);
|
|
431
|
+
const d = function(v) {
|
|
299
432
|
return {
|
|
300
|
-
x: (
|
|
301
|
-
y: (
|
|
433
|
+
x: (v.x - tx) * cos$1(a) - (v.y - ty) * sin$1(a),
|
|
434
|
+
y: (v.x - tx) * sin$1(a) + (v.y - ty) * cos$1(a)
|
|
302
435
|
};
|
|
303
436
|
};
|
|
304
|
-
return
|
|
437
|
+
return points.map(d);
|
|
305
438
|
},
|
|
306
|
-
roots: function(
|
|
307
|
-
|
|
439
|
+
roots: function(points, line) {
|
|
440
|
+
line = line || {
|
|
308
441
|
p1: {
|
|
309
442
|
x: 0,
|
|
310
443
|
y: 0
|
|
@@ -314,694 +447,1147 @@ var c = Math.PI, l = 2 * c, u = c / 2, f = 1e-6, p = 2 ** 53 - 1 || 900719925474
|
|
|
314
447
|
y: 0
|
|
315
448
|
}
|
|
316
449
|
};
|
|
317
|
-
|
|
318
|
-
|
|
450
|
+
const order = points.length - 1;
|
|
451
|
+
const aligned = utils.align(points, line);
|
|
452
|
+
const reduce = function(t) {
|
|
453
|
+
return 0 <= t && t <= 1;
|
|
319
454
|
};
|
|
320
|
-
if (
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
455
|
+
if (order === 2) {
|
|
456
|
+
const a = aligned[0].y;
|
|
457
|
+
const b = aligned[1].y;
|
|
458
|
+
const c = aligned[2].y;
|
|
459
|
+
const d = a - 2 * b + c;
|
|
460
|
+
if (d !== 0) {
|
|
461
|
+
const m1 = -sqrt$1(b * b - a * c);
|
|
462
|
+
const m2 = -a + b;
|
|
463
|
+
return [-(m1 + m2) / d, -(-m1 + m2) / d].filter(reduce);
|
|
464
|
+
} else if (b !== c && d === 0) return [(2 * b - c) / (2 * b - 2 * c)].filter(reduce);
|
|
465
|
+
return [];
|
|
466
|
+
}
|
|
467
|
+
const pa = aligned[0].y;
|
|
468
|
+
const pb = aligned[1].y;
|
|
469
|
+
const pc = aligned[2].y;
|
|
470
|
+
const pd = aligned[3].y;
|
|
471
|
+
let d = -pa + 3 * pb - 3 * pc + pd;
|
|
472
|
+
let a = 3 * pa - 6 * pb + 3 * pc;
|
|
473
|
+
let b = -3 * pa + 3 * pb;
|
|
474
|
+
let c = pa;
|
|
475
|
+
if (utils.approximately(d, 0)) {
|
|
476
|
+
if (utils.approximately(a, 0)) {
|
|
477
|
+
if (utils.approximately(b, 0)) return [];
|
|
478
|
+
return [-c / b].filter(reduce);
|
|
325
479
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if (g.approximately(m, 0)) {
|
|
330
|
-
if (g.approximately(h, 0)) return g.approximately(_, 0) ? [] : [-v / _].filter(reduce);
|
|
331
|
-
let e = o(_ * _ - 4 * h * v), n = 2 * h;
|
|
332
|
-
return [(e - _) / n, (-_ - e) / n].filter(reduce);
|
|
333
|
-
}
|
|
334
|
-
h /= m, _ /= m, v /= m;
|
|
335
|
-
let y = (3 * _ - h * h) / 3, b = y / 3, x = (2 * h * h * h - 9 * h * _ + 27 * v) / 27, S = x / 2, C = S * S + b * b * b, w, T, E, D, O;
|
|
336
|
-
if (C < 0) {
|
|
337
|
-
let e = -y / 3, r = o(e * e * e), a = -x / (2 * r), s = i(a < -1 ? -1 : a > 1 ? 1 : a), c = 2 * crt(r);
|
|
338
|
-
return E = c * n(s / 3) - h / 3, D = c * n((s + l) / 3) - h / 3, O = c * n((s + 2 * l) / 3) - h / 3, [
|
|
339
|
-
E,
|
|
340
|
-
D,
|
|
341
|
-
O
|
|
342
|
-
].filter(reduce);
|
|
480
|
+
const q = sqrt$1(b * b - 4 * a * c);
|
|
481
|
+
const a2 = 2 * a;
|
|
482
|
+
return [(q - b) / a2, (-b - q) / a2].filter(reduce);
|
|
343
483
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
484
|
+
a /= d;
|
|
485
|
+
b /= d;
|
|
486
|
+
c /= d;
|
|
487
|
+
const p = (3 * b - a * a) / 3;
|
|
488
|
+
const p3 = p / 3;
|
|
489
|
+
const q = (2 * a * a * a - 9 * a * b + 27 * c) / 27;
|
|
490
|
+
const q2 = q / 2;
|
|
491
|
+
const discriminant = q2 * q2 + p3 * p3 * p3;
|
|
492
|
+
let u1;
|
|
493
|
+
let v1;
|
|
494
|
+
let x1;
|
|
495
|
+
let x2;
|
|
496
|
+
let x3;
|
|
497
|
+
if (discriminant < 0) {
|
|
498
|
+
const mp3 = -p / 3;
|
|
499
|
+
const r = sqrt$1(mp3 * mp3 * mp3);
|
|
500
|
+
const t = -q / (2 * r);
|
|
501
|
+
const phi = acos$1(t < -1 ? -1 : t > 1 ? 1 : t);
|
|
502
|
+
const t1 = 2 * crt(r);
|
|
503
|
+
x1 = t1 * cos$1(phi / 3) - a / 3;
|
|
504
|
+
x2 = t1 * cos$1((phi + tau) / 3) - a / 3;
|
|
505
|
+
x3 = t1 * cos$1((phi + 2 * tau) / 3) - a / 3;
|
|
506
|
+
return [
|
|
507
|
+
x1,
|
|
508
|
+
x2,
|
|
509
|
+
x3
|
|
510
|
+
].filter(reduce);
|
|
511
|
+
} else if (discriminant === 0) {
|
|
512
|
+
u1 = q2 < 0 ? crt(-q2) : -crt(q2);
|
|
513
|
+
x1 = 2 * u1 - a / 3;
|
|
514
|
+
x2 = -u1 - a / 3;
|
|
515
|
+
return [x1, x2].filter(reduce);
|
|
516
|
+
} else {
|
|
517
|
+
const sd = sqrt$1(discriminant);
|
|
518
|
+
u1 = crt(-q2 + sd);
|
|
519
|
+
v1 = crt(q2 + sd);
|
|
520
|
+
return [u1 - v1 - a / 3].filter(reduce);
|
|
348
521
|
}
|
|
349
522
|
},
|
|
350
|
-
droots: function(
|
|
351
|
-
if (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
523
|
+
droots: function(p) {
|
|
524
|
+
if (p.length === 3) {
|
|
525
|
+
const a = p[0];
|
|
526
|
+
const b = p[1];
|
|
527
|
+
const c = p[2];
|
|
528
|
+
const d = a - 2 * b + c;
|
|
529
|
+
if (d !== 0) {
|
|
530
|
+
const m1 = -sqrt$1(b * b - a * c);
|
|
531
|
+
const m2 = -a + b;
|
|
532
|
+
return [-(m1 + m2) / d, -(-m1 + m2) / d];
|
|
533
|
+
} else if (b !== c && d === 0) return [(2 * b - c) / (2 * (b - c))];
|
|
534
|
+
return [];
|
|
358
535
|
}
|
|
359
|
-
if (
|
|
360
|
-
|
|
361
|
-
|
|
536
|
+
if (p.length === 2) {
|
|
537
|
+
const a = p[0];
|
|
538
|
+
const b = p[1];
|
|
539
|
+
if (a !== b) return [a / (a - b)];
|
|
540
|
+
return [];
|
|
362
541
|
}
|
|
363
542
|
return [];
|
|
364
543
|
},
|
|
365
|
-
curvature: function(
|
|
366
|
-
let
|
|
367
|
-
|
|
544
|
+
curvature: function(t, d1, d2, _3d, kOnly) {
|
|
545
|
+
let num;
|
|
546
|
+
let dnm;
|
|
547
|
+
let adk;
|
|
548
|
+
let dk;
|
|
549
|
+
let k = 0;
|
|
550
|
+
let r = 0;
|
|
551
|
+
const d = utils.compute(t, d1);
|
|
552
|
+
const dd = utils.compute(t, d2);
|
|
553
|
+
const qdsum = d.x * d.x + d.y * d.y;
|
|
554
|
+
if (_3d) {
|
|
555
|
+
num = sqrt$1(pow(d.y * dd.z - dd.y * d.z, 2) + pow(d.z * dd.x - dd.z * d.x, 2) + pow(d.x * dd.y - dd.x * d.y, 2));
|
|
556
|
+
dnm = pow(qdsum + d.z * d.z, 3 / 2);
|
|
557
|
+
} else {
|
|
558
|
+
num = d.x * dd.y - d.y * dd.x;
|
|
559
|
+
dnm = pow(qdsum, 3 / 2);
|
|
560
|
+
}
|
|
561
|
+
if (num === 0 || dnm === 0) return {
|
|
368
562
|
k: 0,
|
|
369
563
|
r: 0
|
|
370
564
|
};
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
565
|
+
k = num / dnm;
|
|
566
|
+
r = dnm / num;
|
|
567
|
+
if (!kOnly) {
|
|
568
|
+
const pk = utils.curvature(t - .001, d1, d2, _3d, true).k;
|
|
569
|
+
const nk = utils.curvature(t + .001, d1, d2, _3d, true).k;
|
|
570
|
+
dk = (nk - k + (k - pk)) / 2;
|
|
571
|
+
adk = (abs$1(nk - k) + abs$1(k - pk)) / 2;
|
|
374
572
|
}
|
|
375
573
|
return {
|
|
376
|
-
k
|
|
377
|
-
r
|
|
378
|
-
dk
|
|
379
|
-
adk
|
|
574
|
+
k,
|
|
575
|
+
r,
|
|
576
|
+
dk,
|
|
577
|
+
adk
|
|
380
578
|
};
|
|
381
579
|
},
|
|
382
|
-
inflections: function(
|
|
383
|
-
if (
|
|
384
|
-
|
|
385
|
-
p1:
|
|
386
|
-
p2:
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
580
|
+
inflections: function(points) {
|
|
581
|
+
if (points.length < 4) return [];
|
|
582
|
+
const p = utils.align(points, {
|
|
583
|
+
p1: points[0],
|
|
584
|
+
p2: points.slice(-1)[0]
|
|
585
|
+
});
|
|
586
|
+
const a = p[2].x * p[1].y;
|
|
587
|
+
const b = p[3].x * p[1].y;
|
|
588
|
+
const c = p[1].x * p[2].y;
|
|
589
|
+
const d = p[3].x * p[2].y;
|
|
590
|
+
const v1 = 18 * (-3 * a + 2 * b + 3 * c - d);
|
|
591
|
+
const v2 = 18 * (3 * a - b - 3 * c);
|
|
592
|
+
const v3 = 18 * (c - a);
|
|
593
|
+
if (utils.approximately(v1, 0)) {
|
|
594
|
+
if (!utils.approximately(v2, 0)) {
|
|
595
|
+
let t = -v3 / v2;
|
|
596
|
+
if (0 <= t && t <= 1) return [t];
|
|
392
597
|
}
|
|
393
598
|
return [];
|
|
394
599
|
}
|
|
395
|
-
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
if (
|
|
399
|
-
|
|
400
|
-
return [(
|
|
401
|
-
return 0 <=
|
|
600
|
+
const d2 = 2 * v1;
|
|
601
|
+
if (utils.approximately(d2, 0)) return [];
|
|
602
|
+
const trm = v2 * v2 - 4 * v1 * v3;
|
|
603
|
+
if (trm < 0) return [];
|
|
604
|
+
const sq = Math.sqrt(trm);
|
|
605
|
+
return [(sq - v2) / d2, -(v2 + sq) / d2].filter(function(r) {
|
|
606
|
+
return 0 <= r && r <= 1;
|
|
402
607
|
});
|
|
403
608
|
},
|
|
404
|
-
bboxoverlap: function(
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
609
|
+
bboxoverlap: function(b1, b2) {
|
|
610
|
+
const dims = ["x", "y"];
|
|
611
|
+
const len = dims.length;
|
|
612
|
+
for (let i = 0, dim, l, t, d; i < len; i++) {
|
|
613
|
+
dim = dims[i];
|
|
614
|
+
l = b1[dim].mid;
|
|
615
|
+
t = b2[dim].mid;
|
|
616
|
+
d = (b1[dim].size + b2[dim].size) / 2;
|
|
617
|
+
if (abs$1(l - t) >= d) return false;
|
|
618
|
+
}
|
|
619
|
+
return true;
|
|
408
620
|
},
|
|
409
|
-
expandbox: function(
|
|
410
|
-
|
|
621
|
+
expandbox: function(bbox, _bbox) {
|
|
622
|
+
if (_bbox.x.min < bbox.x.min) bbox.x.min = _bbox.x.min;
|
|
623
|
+
if (_bbox.y.min < bbox.y.min) bbox.y.min = _bbox.y.min;
|
|
624
|
+
if (_bbox.z && _bbox.z.min < bbox.z.min) bbox.z.min = _bbox.z.min;
|
|
625
|
+
if (_bbox.x.max > bbox.x.max) bbox.x.max = _bbox.x.max;
|
|
626
|
+
if (_bbox.y.max > bbox.y.max) bbox.y.max = _bbox.y.max;
|
|
627
|
+
if (_bbox.z && _bbox.z.max > bbox.z.max) bbox.z.max = _bbox.z.max;
|
|
628
|
+
bbox.x.mid = (bbox.x.min + bbox.x.max) / 2;
|
|
629
|
+
bbox.y.mid = (bbox.y.min + bbox.y.max) / 2;
|
|
630
|
+
if (bbox.z) bbox.z.mid = (bbox.z.min + bbox.z.max) / 2;
|
|
631
|
+
bbox.x.size = bbox.x.max - bbox.x.min;
|
|
632
|
+
bbox.y.size = bbox.y.max - bbox.y.min;
|
|
633
|
+
if (bbox.z) bbox.z.size = bbox.z.max - bbox.z.min;
|
|
411
634
|
},
|
|
412
|
-
pairiteration: function(
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
635
|
+
pairiteration: function(c1, c2, curveIntersectionThreshold) {
|
|
636
|
+
const c1b = c1.bbox();
|
|
637
|
+
const c2b = c2.bbox();
|
|
638
|
+
const r = 1e5;
|
|
639
|
+
const threshold = curveIntersectionThreshold || .5;
|
|
640
|
+
if (c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold) return [(r * (c1._t1 + c1._t2) / 2 | 0) / r + "/" + (r * (c2._t1 + c2._t2) / 2 | 0) / r];
|
|
641
|
+
let cc1 = c1.split(.5);
|
|
642
|
+
let cc2 = c2.split(.5);
|
|
643
|
+
let pairs = [
|
|
416
644
|
{
|
|
417
|
-
left:
|
|
418
|
-
right:
|
|
645
|
+
left: cc1.left,
|
|
646
|
+
right: cc2.left
|
|
419
647
|
},
|
|
420
648
|
{
|
|
421
|
-
left:
|
|
422
|
-
right:
|
|
649
|
+
left: cc1.left,
|
|
650
|
+
right: cc2.right
|
|
423
651
|
},
|
|
424
652
|
{
|
|
425
|
-
left:
|
|
426
|
-
right:
|
|
653
|
+
left: cc1.right,
|
|
654
|
+
right: cc2.right
|
|
427
655
|
},
|
|
428
656
|
{
|
|
429
|
-
left:
|
|
430
|
-
right:
|
|
657
|
+
left: cc1.right,
|
|
658
|
+
right: cc2.left
|
|
431
659
|
}
|
|
432
660
|
];
|
|
433
|
-
|
|
434
|
-
return
|
|
661
|
+
pairs = pairs.filter(function(pair) {
|
|
662
|
+
return utils.bboxoverlap(pair.left.bbox(), pair.right.bbox());
|
|
435
663
|
});
|
|
436
|
-
let
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
664
|
+
let results = [];
|
|
665
|
+
if (pairs.length === 0) return results;
|
|
666
|
+
pairs.forEach(function(pair) {
|
|
667
|
+
results = results.concat(utils.pairiteration(pair.left, pair.right, threshold));
|
|
668
|
+
});
|
|
669
|
+
results = results.filter(function(v, i) {
|
|
670
|
+
return results.indexOf(v) === i;
|
|
671
|
+
});
|
|
672
|
+
return results;
|
|
442
673
|
},
|
|
443
|
-
getccenter: function(
|
|
444
|
-
|
|
445
|
-
|
|
674
|
+
getccenter: function(p1, p2, p3) {
|
|
675
|
+
const dx1 = p2.x - p1.x;
|
|
676
|
+
const dy1 = p2.y - p1.y;
|
|
677
|
+
const dx2 = p3.x - p2.x;
|
|
678
|
+
const dy2 = p3.y - p2.y;
|
|
679
|
+
const dx1p = dx1 * cos$1(quart) - dy1 * sin$1(quart);
|
|
680
|
+
const dy1p = dx1 * sin$1(quart) + dy1 * cos$1(quart);
|
|
681
|
+
const dx2p = dx2 * cos$1(quart) - dy2 * sin$1(quart);
|
|
682
|
+
const dy2p = dx2 * sin$1(quart) + dy2 * cos$1(quart);
|
|
683
|
+
const mx1 = (p1.x + p2.x) / 2;
|
|
684
|
+
const my1 = (p1.y + p2.y) / 2;
|
|
685
|
+
const mx2 = (p2.x + p3.x) / 2;
|
|
686
|
+
const my2 = (p2.y + p3.y) / 2;
|
|
687
|
+
const mx1n = mx1 + dx1p;
|
|
688
|
+
const my1n = my1 + dy1p;
|
|
689
|
+
const mx2n = mx2 + dx2p;
|
|
690
|
+
const my2n = my2 + dy2p;
|
|
691
|
+
const arc = utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n);
|
|
692
|
+
const r = utils.dist(arc, p1);
|
|
693
|
+
let s = atan2(p1.y - arc.y, p1.x - arc.x);
|
|
694
|
+
let m = atan2(p2.y - arc.y, p2.x - arc.x);
|
|
695
|
+
let e = atan2(p3.y - arc.y, p3.x - arc.x);
|
|
696
|
+
let _;
|
|
697
|
+
if (s < e) {
|
|
698
|
+
if (s > m || m > e) s += tau;
|
|
699
|
+
if (s > e) {
|
|
700
|
+
_ = e;
|
|
701
|
+
e = s;
|
|
702
|
+
s = _;
|
|
703
|
+
}
|
|
704
|
+
} else if (e < m && m < s) {
|
|
705
|
+
_ = e;
|
|
706
|
+
e = s;
|
|
707
|
+
s = _;
|
|
708
|
+
} else e += tau;
|
|
709
|
+
arc.s = s;
|
|
710
|
+
arc.e = e;
|
|
711
|
+
arc.r = r;
|
|
712
|
+
return arc;
|
|
446
713
|
},
|
|
447
|
-
numberSort: function(
|
|
448
|
-
return
|
|
714
|
+
numberSort: function(a, b) {
|
|
715
|
+
return a - b;
|
|
449
716
|
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
|
|
717
|
+
};
|
|
718
|
+
//#endregion
|
|
719
|
+
//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/poly-bezier.js
|
|
720
|
+
/**
|
|
721
|
+
* Poly Bezier
|
|
722
|
+
* @param {[type]} curves [description]
|
|
723
|
+
*/
|
|
724
|
+
var PolyBezier = class PolyBezier {
|
|
725
|
+
constructor(curves) {
|
|
726
|
+
this.curves = [];
|
|
727
|
+
this._3d = false;
|
|
728
|
+
if (!!curves) {
|
|
729
|
+
this.curves = curves;
|
|
730
|
+
this._3d = this.curves[0]._3d;
|
|
731
|
+
}
|
|
453
732
|
}
|
|
454
733
|
valueOf() {
|
|
455
734
|
return this.toString();
|
|
456
735
|
}
|
|
457
736
|
toString() {
|
|
458
|
-
return "[" + this.curves.map(function(
|
|
459
|
-
return
|
|
737
|
+
return "[" + this.curves.map(function(curve) {
|
|
738
|
+
return utils.pointsToString(curve.points);
|
|
460
739
|
}).join(", ") + "]";
|
|
461
740
|
}
|
|
462
|
-
addCurve(
|
|
463
|
-
this.curves.push(
|
|
741
|
+
addCurve(curve) {
|
|
742
|
+
this.curves.push(curve);
|
|
743
|
+
this._3d = this._3d || curve._3d;
|
|
464
744
|
}
|
|
465
745
|
length() {
|
|
466
|
-
return this.curves.map(function(
|
|
467
|
-
return
|
|
468
|
-
}).reduce(function(
|
|
469
|
-
return
|
|
746
|
+
return this.curves.map(function(v) {
|
|
747
|
+
return v.length();
|
|
748
|
+
}).reduce(function(a, b) {
|
|
749
|
+
return a + b;
|
|
470
750
|
});
|
|
471
751
|
}
|
|
472
|
-
curve(
|
|
473
|
-
return this.curves[
|
|
752
|
+
curve(idx) {
|
|
753
|
+
return this.curves[idx];
|
|
474
754
|
}
|
|
475
755
|
bbox() {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
756
|
+
const c = this.curves;
|
|
757
|
+
var bbox = c[0].bbox();
|
|
758
|
+
for (var i = 1; i < c.length; i++) utils.expandbox(bbox, c[i].bbox());
|
|
759
|
+
return bbox;
|
|
760
|
+
}
|
|
761
|
+
offset(d) {
|
|
762
|
+
const offset = [];
|
|
763
|
+
this.curves.forEach(function(v) {
|
|
764
|
+
offset.push(...v.offset(d));
|
|
765
|
+
});
|
|
766
|
+
return new PolyBezier(offset);
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region ../../node_modules/.pnpm/bezier-js@6.1.4/node_modules/bezier-js/src/bezier.js
|
|
771
|
+
/**
|
|
772
|
+
A javascript Bezier curve library by Pomax.
|
|
773
|
+
|
|
774
|
+
Based on http://pomax.github.io/bezierinfo
|
|
775
|
+
|
|
776
|
+
This code is MIT licensed.
|
|
777
|
+
**/
|
|
778
|
+
var { abs, min, max, cos, sin, acos, sqrt } = Math;
|
|
779
|
+
var pi = Math.PI;
|
|
780
|
+
/**
|
|
781
|
+
* Bezier curve constructor.
|
|
782
|
+
*
|
|
783
|
+
* ...docs pending...
|
|
784
|
+
*/
|
|
785
|
+
var Bezier = class Bezier {
|
|
786
|
+
constructor(coords) {
|
|
787
|
+
let args = coords && coords.forEach ? coords : Array.from(arguments).slice();
|
|
788
|
+
let coordlen = false;
|
|
789
|
+
if (typeof args[0] === "object") {
|
|
790
|
+
coordlen = args.length;
|
|
791
|
+
const newargs = [];
|
|
792
|
+
args.forEach(function(point) {
|
|
493
793
|
[
|
|
494
794
|
"x",
|
|
495
795
|
"y",
|
|
496
796
|
"z"
|
|
497
|
-
].forEach(function(
|
|
498
|
-
|
|
797
|
+
].forEach(function(d) {
|
|
798
|
+
if (typeof point[d] !== "undefined") newargs.push(point[d]);
|
|
499
799
|
});
|
|
500
|
-
})
|
|
800
|
+
});
|
|
801
|
+
args = newargs;
|
|
501
802
|
}
|
|
502
|
-
let
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
803
|
+
let higher = false;
|
|
804
|
+
const len = args.length;
|
|
805
|
+
if (coordlen) {
|
|
806
|
+
if (coordlen > 4) {
|
|
807
|
+
if (arguments.length !== 1) throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");
|
|
808
|
+
higher = true;
|
|
507
809
|
}
|
|
508
|
-
} else if (
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
810
|
+
} else if (len !== 6 && len !== 8 && len !== 9 && len !== 12) {
|
|
811
|
+
if (arguments.length !== 1) throw new Error("Only new Bezier(point[]) is accepted for 4th and higher order curves");
|
|
812
|
+
}
|
|
813
|
+
const _3d = this._3d = !higher && (len === 9 || len === 12) || coords && coords[0] && typeof coords[0].z !== "undefined";
|
|
814
|
+
const points = this.points = [];
|
|
815
|
+
for (let idx = 0, step = _3d ? 3 : 2; idx < len; idx += step) {
|
|
816
|
+
var point = {
|
|
817
|
+
x: args[idx],
|
|
818
|
+
y: args[idx + 1]
|
|
514
819
|
};
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
820
|
+
if (_3d) point.z = args[idx + 2];
|
|
821
|
+
points.push(point);
|
|
822
|
+
}
|
|
823
|
+
const order = this.order = points.length - 1;
|
|
824
|
+
const dims = this.dims = ["x", "y"];
|
|
825
|
+
if (_3d) dims.push("z");
|
|
826
|
+
this.dimlen = dims.length;
|
|
827
|
+
const aligned = utils.align(points, {
|
|
828
|
+
p1: points[0],
|
|
829
|
+
p2: points[order]
|
|
830
|
+
});
|
|
831
|
+
const baselength = utils.dist(points[0], points[order]);
|
|
832
|
+
this._linear = aligned.reduce((t, p) => t + abs(p.y), 0) < baselength / 50;
|
|
833
|
+
this._lut = [];
|
|
834
|
+
this._t1 = 0;
|
|
835
|
+
this._t2 = 1;
|
|
836
|
+
this.update();
|
|
837
|
+
}
|
|
838
|
+
static quadraticFromPoints(p1, p2, p3, t) {
|
|
839
|
+
if (typeof t === "undefined") t = .5;
|
|
840
|
+
if (t === 0) return new Bezier(p2, p2, p3);
|
|
841
|
+
if (t === 1) return new Bezier(p1, p2, p2);
|
|
842
|
+
const abc = Bezier.getABC(2, p1, p2, p3, t);
|
|
843
|
+
return new Bezier(p1, abc.A, p3);
|
|
844
|
+
}
|
|
845
|
+
static cubicFromPoints(S, B, E, t, d1) {
|
|
846
|
+
if (typeof t === "undefined") t = .5;
|
|
847
|
+
const abc = Bezier.getABC(3, S, B, E, t);
|
|
848
|
+
if (typeof d1 === "undefined") d1 = utils.dist(B, abc.C);
|
|
849
|
+
const d2 = d1 * (1 - t) / t;
|
|
850
|
+
const selen = utils.dist(S, E);
|
|
851
|
+
const lx = (E.x - S.x) / selen;
|
|
852
|
+
const ly = (E.y - S.y) / selen;
|
|
853
|
+
const bx1 = d1 * lx;
|
|
854
|
+
const by1 = d1 * ly;
|
|
855
|
+
const bx2 = d2 * lx;
|
|
856
|
+
const by2 = d2 * ly;
|
|
857
|
+
const e1 = {
|
|
858
|
+
x: B.x - bx1,
|
|
859
|
+
y: B.y - by1
|
|
553
860
|
};
|
|
554
|
-
|
|
861
|
+
const e2 = {
|
|
862
|
+
x: B.x + bx2,
|
|
863
|
+
y: B.y + by2
|
|
864
|
+
};
|
|
865
|
+
const A = abc.A;
|
|
866
|
+
const v1 = {
|
|
867
|
+
x: A.x + (e1.x - A.x) / (1 - t),
|
|
868
|
+
y: A.y + (e1.y - A.y) / (1 - t)
|
|
869
|
+
};
|
|
870
|
+
const v2 = {
|
|
871
|
+
x: A.x + (e2.x - A.x) / t,
|
|
872
|
+
y: A.y + (e2.y - A.y) / t
|
|
873
|
+
};
|
|
874
|
+
const nc1 = {
|
|
875
|
+
x: S.x + (v1.x - S.x) / t,
|
|
876
|
+
y: S.y + (v1.y - S.y) / t
|
|
877
|
+
};
|
|
878
|
+
const nc2 = {
|
|
879
|
+
x: E.x + (v2.x - E.x) / (1 - t),
|
|
880
|
+
y: E.y + (v2.y - E.y) / (1 - t)
|
|
881
|
+
};
|
|
882
|
+
return new Bezier(S, nc1, nc2, E);
|
|
555
883
|
}
|
|
556
884
|
static getUtils() {
|
|
557
|
-
return
|
|
885
|
+
return utils;
|
|
558
886
|
}
|
|
559
887
|
getUtils() {
|
|
560
888
|
return Bezier.getUtils();
|
|
561
889
|
}
|
|
562
890
|
static get PolyBezier() {
|
|
563
|
-
return
|
|
891
|
+
return PolyBezier;
|
|
564
892
|
}
|
|
565
893
|
valueOf() {
|
|
566
894
|
return this.toString();
|
|
567
895
|
}
|
|
568
896
|
toString() {
|
|
569
|
-
return
|
|
897
|
+
return utils.pointsToString(this.points);
|
|
570
898
|
}
|
|
571
899
|
toSVG() {
|
|
572
|
-
if (this._3d) return
|
|
573
|
-
|
|
900
|
+
if (this._3d) return false;
|
|
901
|
+
const p = this.points;
|
|
902
|
+
const s = [
|
|
574
903
|
"M",
|
|
575
|
-
|
|
576
|
-
|
|
904
|
+
p[0].x,
|
|
905
|
+
p[0].y,
|
|
577
906
|
this.order === 2 ? "Q" : "C"
|
|
578
907
|
];
|
|
579
|
-
for (let
|
|
580
|
-
|
|
908
|
+
for (let i = 1, last = p.length; i < last; i++) {
|
|
909
|
+
s.push(p[i].x);
|
|
910
|
+
s.push(p[i].y);
|
|
911
|
+
}
|
|
912
|
+
return s.join(" ");
|
|
581
913
|
}
|
|
582
|
-
setRatios(
|
|
583
|
-
if (
|
|
584
|
-
this.ratios =
|
|
914
|
+
setRatios(ratios) {
|
|
915
|
+
if (ratios.length !== this.points.length) throw new Error("incorrect number of ratio values");
|
|
916
|
+
this.ratios = ratios;
|
|
917
|
+
this._lut = [];
|
|
585
918
|
}
|
|
586
919
|
verify() {
|
|
587
|
-
|
|
588
|
-
|
|
920
|
+
const print = this.coordDigest();
|
|
921
|
+
if (print !== this._print) {
|
|
922
|
+
this._print = print;
|
|
923
|
+
this.update();
|
|
924
|
+
}
|
|
589
925
|
}
|
|
590
926
|
coordDigest() {
|
|
591
|
-
return this.points.map(function(
|
|
592
|
-
return "" +
|
|
927
|
+
return this.points.map(function(c, pos) {
|
|
928
|
+
return "" + pos + c.x + c.y + (c.z ? c.z : 0);
|
|
593
929
|
}).join("");
|
|
594
930
|
}
|
|
595
931
|
update() {
|
|
596
|
-
this._lut = []
|
|
932
|
+
this._lut = [];
|
|
933
|
+
this.dpoints = utils.derive(this.points, this._3d);
|
|
934
|
+
this.computedirection();
|
|
597
935
|
}
|
|
598
936
|
computedirection() {
|
|
599
|
-
|
|
600
|
-
|
|
937
|
+
const points = this.points;
|
|
938
|
+
const angle = utils.angle(points[0], points[this.order], points[1]);
|
|
939
|
+
this.clockwise = angle > 0;
|
|
601
940
|
}
|
|
602
941
|
length() {
|
|
603
|
-
return
|
|
942
|
+
return utils.length(this.derivative.bind(this));
|
|
604
943
|
}
|
|
605
|
-
static getABC(
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
944
|
+
static getABC(order = 2, S, B, E, t = .5) {
|
|
945
|
+
const u = utils.projectionratio(t, order);
|
|
946
|
+
const um = 1 - u;
|
|
947
|
+
const C = {
|
|
948
|
+
x: u * S.x + um * E.x,
|
|
949
|
+
y: u * S.y + um * E.y
|
|
950
|
+
};
|
|
951
|
+
const s = utils.abcratio(t, order);
|
|
610
952
|
return {
|
|
611
953
|
A: {
|
|
612
|
-
x:
|
|
613
|
-
y:
|
|
954
|
+
x: B.x + (B.x - C.x) / s,
|
|
955
|
+
y: B.y + (B.y - C.y) / s
|
|
614
956
|
},
|
|
615
|
-
B
|
|
616
|
-
C
|
|
617
|
-
S
|
|
618
|
-
E
|
|
957
|
+
B,
|
|
958
|
+
C,
|
|
959
|
+
S,
|
|
960
|
+
E
|
|
619
961
|
};
|
|
620
962
|
}
|
|
621
|
-
getABC(
|
|
622
|
-
|
|
623
|
-
let
|
|
624
|
-
|
|
963
|
+
getABC(t, B) {
|
|
964
|
+
B = B || this.get(t);
|
|
965
|
+
let S = this.points[0];
|
|
966
|
+
let E = this.points[this.order];
|
|
967
|
+
return Bezier.getABC(this.order, S, B, E, t);
|
|
625
968
|
}
|
|
626
|
-
getLUT(
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
969
|
+
getLUT(steps) {
|
|
970
|
+
this.verify();
|
|
971
|
+
steps = steps || 100;
|
|
972
|
+
if (this._lut.length === steps + 1) return this._lut;
|
|
973
|
+
this._lut = [];
|
|
974
|
+
steps++;
|
|
975
|
+
this._lut = [];
|
|
976
|
+
for (let i = 0, p, t; i < steps; i++) {
|
|
977
|
+
t = i / (steps - 1);
|
|
978
|
+
p = this.compute(t);
|
|
979
|
+
p.t = t;
|
|
980
|
+
this._lut.push(p);
|
|
981
|
+
}
|
|
630
982
|
return this._lut;
|
|
631
983
|
}
|
|
632
|
-
on(
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
984
|
+
on(point, error) {
|
|
985
|
+
error = error || 5;
|
|
986
|
+
const lut = this.getLUT();
|
|
987
|
+
const hits = [];
|
|
988
|
+
for (let i = 0, c, t = 0; i < lut.length; i++) {
|
|
989
|
+
c = lut[i];
|
|
990
|
+
if (utils.dist(c, point) < error) {
|
|
991
|
+
hits.push(c);
|
|
992
|
+
t += i / lut.length;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (!hits.length) return false;
|
|
996
|
+
return t /= hits.length;
|
|
637
997
|
}
|
|
638
|
-
project(
|
|
639
|
-
|
|
640
|
-
l
|
|
641
|
-
|
|
642
|
-
|
|
998
|
+
project(point) {
|
|
999
|
+
const LUT = this.getLUT();
|
|
1000
|
+
const l = LUT.length - 1;
|
|
1001
|
+
const closest = utils.closest(LUT, point);
|
|
1002
|
+
const mpos = closest.mpos;
|
|
1003
|
+
const t1 = (mpos - 1) / l;
|
|
1004
|
+
const t2 = (mpos + 1) / l;
|
|
1005
|
+
const step = .1 / l;
|
|
1006
|
+
let mdist = closest.mdist;
|
|
1007
|
+
let t = t1;
|
|
1008
|
+
let ft = t;
|
|
1009
|
+
let p;
|
|
1010
|
+
mdist += 1;
|
|
1011
|
+
for (let d; t < t2 + step; t += step) {
|
|
1012
|
+
p = this.compute(t);
|
|
1013
|
+
d = utils.dist(point, p);
|
|
1014
|
+
if (d < mdist) {
|
|
1015
|
+
mdist = d;
|
|
1016
|
+
ft = t;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
ft = ft < 0 ? 0 : ft > 1 ? 1 : ft;
|
|
1020
|
+
p = this.compute(ft);
|
|
1021
|
+
p.t = ft;
|
|
1022
|
+
p.d = mdist;
|
|
1023
|
+
return p;
|
|
643
1024
|
}
|
|
644
|
-
get(
|
|
645
|
-
return this.compute(
|
|
1025
|
+
get(t) {
|
|
1026
|
+
return this.compute(t);
|
|
646
1027
|
}
|
|
647
|
-
point(
|
|
648
|
-
return this.points[
|
|
1028
|
+
point(idx) {
|
|
1029
|
+
return this.points[idx];
|
|
649
1030
|
}
|
|
650
|
-
compute(
|
|
651
|
-
|
|
1031
|
+
compute(t) {
|
|
1032
|
+
if (this.ratios) return utils.computeWithRatios(t, this.points, this.ratios, this._3d);
|
|
1033
|
+
return utils.compute(t, this.points, this._3d, this.ratios);
|
|
652
1034
|
}
|
|
653
1035
|
raise() {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
1036
|
+
const p = this.points;
|
|
1037
|
+
const np = [p[0]];
|
|
1038
|
+
const k = p.length;
|
|
1039
|
+
for (let i = 1, pi, pim; i < k; i++) {
|
|
1040
|
+
pi = p[i];
|
|
1041
|
+
pim = p[i - 1];
|
|
1042
|
+
np[i] = {
|
|
1043
|
+
x: (k - i) / k * pi.x + i / k * pim.x,
|
|
1044
|
+
y: (k - i) / k * pi.y + i / k * pim.y
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
np[k] = p[k - 1];
|
|
1048
|
+
return new Bezier(np);
|
|
660
1049
|
}
|
|
661
|
-
derivative(
|
|
662
|
-
return
|
|
1050
|
+
derivative(t) {
|
|
1051
|
+
return utils.compute(t, this.dpoints[0], this._3d);
|
|
663
1052
|
}
|
|
664
|
-
dderivative(
|
|
665
|
-
return
|
|
1053
|
+
dderivative(t) {
|
|
1054
|
+
return utils.compute(t, this.dpoints[1], this._3d);
|
|
666
1055
|
}
|
|
667
1056
|
align() {
|
|
668
|
-
let
|
|
669
|
-
return new Bezier(
|
|
670
|
-
p1:
|
|
671
|
-
p2:
|
|
1057
|
+
let p = this.points;
|
|
1058
|
+
return new Bezier(utils.align(p, {
|
|
1059
|
+
p1: p[0],
|
|
1060
|
+
p2: p[p.length - 1]
|
|
672
1061
|
}));
|
|
673
1062
|
}
|
|
674
|
-
curvature(
|
|
675
|
-
return
|
|
1063
|
+
curvature(t) {
|
|
1064
|
+
return utils.curvature(t, this.dpoints[0], this.dpoints[1], this._3d);
|
|
676
1065
|
}
|
|
677
1066
|
inflections() {
|
|
678
|
-
return
|
|
1067
|
+
return utils.inflections(this.points);
|
|
679
1068
|
}
|
|
680
|
-
normal(
|
|
681
|
-
return this._3d ? this.__normal3(
|
|
1069
|
+
normal(t) {
|
|
1070
|
+
return this._3d ? this.__normal3(t) : this.__normal2(t);
|
|
682
1071
|
}
|
|
683
|
-
__normal2(
|
|
684
|
-
|
|
1072
|
+
__normal2(t) {
|
|
1073
|
+
const d = this.derivative(t);
|
|
1074
|
+
const q = sqrt(d.x * d.x + d.y * d.y);
|
|
685
1075
|
return {
|
|
686
|
-
t
|
|
687
|
-
x: -
|
|
688
|
-
y:
|
|
1076
|
+
t,
|
|
1077
|
+
x: -d.y / q,
|
|
1078
|
+
y: d.x / q
|
|
689
1079
|
};
|
|
690
1080
|
}
|
|
691
|
-
__normal3(
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
1081
|
+
__normal3(t) {
|
|
1082
|
+
const r1 = this.derivative(t);
|
|
1083
|
+
const r2 = this.derivative(t + .01);
|
|
1084
|
+
const q1 = sqrt(r1.x * r1.x + r1.y * r1.y + r1.z * r1.z);
|
|
1085
|
+
const q2 = sqrt(r2.x * r2.x + r2.y * r2.y + r2.z * r2.z);
|
|
1086
|
+
r1.x /= q1;
|
|
1087
|
+
r1.y /= q1;
|
|
1088
|
+
r1.z /= q1;
|
|
1089
|
+
r2.x /= q2;
|
|
1090
|
+
r2.y /= q2;
|
|
1091
|
+
r2.z /= q2;
|
|
1092
|
+
const c = {
|
|
1093
|
+
x: r2.y * r1.z - r2.z * r1.y,
|
|
1094
|
+
y: r2.z * r1.x - r2.x * r1.z,
|
|
1095
|
+
z: r2.x * r1.y - r2.y * r1.x
|
|
1096
|
+
};
|
|
1097
|
+
const m = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);
|
|
1098
|
+
c.x /= m;
|
|
1099
|
+
c.y /= m;
|
|
1100
|
+
c.z /= m;
|
|
1101
|
+
const R = [
|
|
1102
|
+
c.x * c.x,
|
|
1103
|
+
c.x * c.y - c.z,
|
|
1104
|
+
c.x * c.z + c.y,
|
|
1105
|
+
c.x * c.y + c.z,
|
|
1106
|
+
c.y * c.y,
|
|
1107
|
+
c.y * c.z - c.x,
|
|
1108
|
+
c.x * c.z - c.y,
|
|
1109
|
+
c.y * c.z + c.x,
|
|
1110
|
+
c.z * c.z
|
|
710
1111
|
];
|
|
711
1112
|
return {
|
|
712
|
-
t
|
|
713
|
-
x:
|
|
714
|
-
y:
|
|
715
|
-
z:
|
|
1113
|
+
t,
|
|
1114
|
+
x: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z,
|
|
1115
|
+
y: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z,
|
|
1116
|
+
z: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z
|
|
716
1117
|
};
|
|
717
1118
|
}
|
|
718
|
-
hull(
|
|
719
|
-
let
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
1119
|
+
hull(t) {
|
|
1120
|
+
let p = this.points;
|
|
1121
|
+
let _p = [];
|
|
1122
|
+
let q = [];
|
|
1123
|
+
let idx = 0;
|
|
1124
|
+
q[idx++] = p[0];
|
|
1125
|
+
q[idx++] = p[1];
|
|
1126
|
+
q[idx++] = p[2];
|
|
1127
|
+
if (this.order === 3) q[idx++] = p[3];
|
|
1128
|
+
while (p.length > 1) {
|
|
1129
|
+
_p = [];
|
|
1130
|
+
for (let i = 0, pt, l = p.length - 1; i < l; i++) {
|
|
1131
|
+
pt = utils.lerp(t, p[i], p[i + 1]);
|
|
1132
|
+
q[idx++] = pt;
|
|
1133
|
+
_p.push(pt);
|
|
1134
|
+
}
|
|
1135
|
+
p = _p;
|
|
724
1136
|
}
|
|
725
|
-
return
|
|
1137
|
+
return q;
|
|
726
1138
|
}
|
|
727
|
-
split(
|
|
728
|
-
if (
|
|
729
|
-
if (
|
|
730
|
-
|
|
1139
|
+
split(t1, t2) {
|
|
1140
|
+
if (t1 === 0 && !!t2) return this.split(t2).left;
|
|
1141
|
+
if (t2 === 1) return this.split(t1).right;
|
|
1142
|
+
const q = this.hull(t1);
|
|
1143
|
+
const result = {
|
|
731
1144
|
left: this.order === 2 ? new Bezier([
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1145
|
+
q[0],
|
|
1146
|
+
q[3],
|
|
1147
|
+
q[5]
|
|
735
1148
|
]) : new Bezier([
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
1149
|
+
q[0],
|
|
1150
|
+
q[4],
|
|
1151
|
+
q[7],
|
|
1152
|
+
q[9]
|
|
740
1153
|
]),
|
|
741
1154
|
right: this.order === 2 ? new Bezier([
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1155
|
+
q[5],
|
|
1156
|
+
q[4],
|
|
1157
|
+
q[2]
|
|
745
1158
|
]) : new Bezier([
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
1159
|
+
q[9],
|
|
1160
|
+
q[8],
|
|
1161
|
+
q[6],
|
|
1162
|
+
q[3]
|
|
750
1163
|
]),
|
|
751
|
-
span:
|
|
1164
|
+
span: q
|
|
752
1165
|
};
|
|
753
|
-
|
|
1166
|
+
result.left._t1 = utils.map(0, 0, 1, this._t1, this._t2);
|
|
1167
|
+
result.left._t2 = utils.map(t1, 0, 1, this._t1, this._t2);
|
|
1168
|
+
result.right._t1 = utils.map(t1, 0, 1, this._t1, this._t2);
|
|
1169
|
+
result.right._t2 = utils.map(1, 0, 1, this._t1, this._t2);
|
|
1170
|
+
if (!t2) return result;
|
|
1171
|
+
t2 = utils.map(t2, t1, 1, 0, 1);
|
|
1172
|
+
return result.right.split(t2).left;
|
|
754
1173
|
}
|
|
755
1174
|
extrema() {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1175
|
+
const result = {};
|
|
1176
|
+
let roots = [];
|
|
1177
|
+
this.dims.forEach(function(dim) {
|
|
1178
|
+
let mfn = function(v) {
|
|
1179
|
+
return v[dim];
|
|
1180
|
+
};
|
|
1181
|
+
let p = this.dpoints[0].map(mfn);
|
|
1182
|
+
result[dim] = utils.droots(p);
|
|
1183
|
+
if (this.order === 3) {
|
|
1184
|
+
p = this.dpoints[1].map(mfn);
|
|
1185
|
+
result[dim] = result[dim].concat(utils.droots(p));
|
|
1186
|
+
}
|
|
1187
|
+
result[dim] = result[dim].filter(function(t) {
|
|
1188
|
+
return t >= 0 && t <= 1;
|
|
1189
|
+
});
|
|
1190
|
+
roots = roots.concat(result[dim].sort(utils.numberSort));
|
|
1191
|
+
}.bind(this));
|
|
1192
|
+
result.values = roots.sort(utils.numberSort).filter(function(v, idx) {
|
|
1193
|
+
return roots.indexOf(v) === idx;
|
|
1194
|
+
});
|
|
1195
|
+
return result;
|
|
767
1196
|
}
|
|
768
1197
|
bbox() {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1198
|
+
const extrema = this.extrema();
|
|
1199
|
+
const result = {};
|
|
1200
|
+
this.dims.forEach(function(d) {
|
|
1201
|
+
result[d] = utils.getminmax(this, d, extrema[d]);
|
|
1202
|
+
}.bind(this));
|
|
1203
|
+
return result;
|
|
1204
|
+
}
|
|
1205
|
+
overlaps(curve) {
|
|
1206
|
+
const lbbox = this.bbox();
|
|
1207
|
+
const tbbox = curve.bbox();
|
|
1208
|
+
return utils.bboxoverlap(lbbox, tbbox);
|
|
1209
|
+
}
|
|
1210
|
+
offset(t, d) {
|
|
1211
|
+
if (typeof d !== "undefined") {
|
|
1212
|
+
const c = this.get(t);
|
|
1213
|
+
const n = this.normal(t);
|
|
1214
|
+
const ret = {
|
|
1215
|
+
c,
|
|
1216
|
+
n,
|
|
1217
|
+
x: c.x + n.x * d,
|
|
1218
|
+
y: c.y + n.y * d
|
|
785
1219
|
};
|
|
786
|
-
|
|
1220
|
+
if (this._3d) ret.z = c.z + n.z * d;
|
|
1221
|
+
return ret;
|
|
787
1222
|
}
|
|
788
1223
|
if (this._linear) {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
1224
|
+
const nv = this.normal(0);
|
|
1225
|
+
const coords = this.points.map(function(p) {
|
|
1226
|
+
const ret = {
|
|
1227
|
+
x: p.x + t * nv.x,
|
|
1228
|
+
y: p.y + t * nv.y
|
|
793
1229
|
};
|
|
794
|
-
|
|
1230
|
+
if (p.z && nv.z) ret.z = p.z + t * nv.z;
|
|
1231
|
+
return ret;
|
|
795
1232
|
});
|
|
796
|
-
return [new Bezier(
|
|
1233
|
+
return [new Bezier(coords)];
|
|
797
1234
|
}
|
|
798
|
-
return this.reduce().map(function(
|
|
799
|
-
|
|
1235
|
+
return this.reduce().map(function(s) {
|
|
1236
|
+
if (s._linear) return s.offset(t)[0];
|
|
1237
|
+
return s.scale(t);
|
|
800
1238
|
});
|
|
801
1239
|
}
|
|
802
1240
|
simple() {
|
|
803
1241
|
if (this.order === 3) {
|
|
804
|
-
|
|
805
|
-
|
|
1242
|
+
const a1 = utils.angle(this.points[0], this.points[3], this.points[1]);
|
|
1243
|
+
const a2 = utils.angle(this.points[0], this.points[3], this.points[2]);
|
|
1244
|
+
if (a1 > 0 && a2 < 0 || a1 < 0 && a2 > 0) return false;
|
|
806
1245
|
}
|
|
807
|
-
|
|
808
|
-
|
|
1246
|
+
const n1 = this.normal(0);
|
|
1247
|
+
const n2 = this.normal(1);
|
|
1248
|
+
let s = n1.x * n2.x + n1.y * n2.y;
|
|
1249
|
+
if (this._3d) s += n1.z * n2.z;
|
|
1250
|
+
return abs(acos(s)) < pi / 3;
|
|
809
1251
|
}
|
|
810
1252
|
reduce() {
|
|
811
|
-
let
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1253
|
+
let i;
|
|
1254
|
+
let t1 = 0;
|
|
1255
|
+
let t2 = 0;
|
|
1256
|
+
let step = .01;
|
|
1257
|
+
let segment;
|
|
1258
|
+
let pass1 = [];
|
|
1259
|
+
let pass2 = [];
|
|
1260
|
+
let extrema = this.extrema().values;
|
|
1261
|
+
if (extrema.indexOf(0) === -1) extrema = [0].concat(extrema);
|
|
1262
|
+
if (extrema.indexOf(1) === -1) extrema.push(1);
|
|
1263
|
+
for (t1 = extrema[0], i = 1; i < extrema.length; i++) {
|
|
1264
|
+
t2 = extrema[i];
|
|
1265
|
+
segment = this.split(t1, t2);
|
|
1266
|
+
segment._t1 = t1;
|
|
1267
|
+
segment._t2 = t2;
|
|
1268
|
+
pass1.push(segment);
|
|
1269
|
+
t1 = t2;
|
|
1270
|
+
}
|
|
1271
|
+
pass1.forEach(function(p1) {
|
|
1272
|
+
t1 = 0;
|
|
1273
|
+
t2 = 0;
|
|
1274
|
+
while (t2 <= 1) for (t2 = t1 + step; t2 <= 1.01; t2 += step) {
|
|
1275
|
+
segment = p1.split(t1, t2);
|
|
1276
|
+
if (!segment.simple()) {
|
|
1277
|
+
t2 -= step;
|
|
1278
|
+
if (abs(t1 - t2) < step) return [];
|
|
1279
|
+
segment = p1.split(t1, t2);
|
|
1280
|
+
segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2);
|
|
1281
|
+
segment._t2 = utils.map(t2, 0, 1, p1._t1, p1._t2);
|
|
1282
|
+
pass2.push(segment);
|
|
1283
|
+
t1 = t2;
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
818
1286
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
1287
|
+
if (t1 < 1) {
|
|
1288
|
+
segment = p1.split(t1, 1);
|
|
1289
|
+
segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2);
|
|
1290
|
+
segment._t2 = p1._t2;
|
|
1291
|
+
pass2.push(segment);
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
return pass2;
|
|
1295
|
+
}
|
|
1296
|
+
translate(v, d1, d2) {
|
|
1297
|
+
d2 = typeof d2 === "number" ? d2 : d1;
|
|
1298
|
+
const o = this.order;
|
|
1299
|
+
let d = this.points.map((_, i) => (1 - i / o) * d1 + i / o * d2);
|
|
1300
|
+
return new Bezier(this.points.map((p, i) => ({
|
|
1301
|
+
x: p.x + v.x * d[i],
|
|
1302
|
+
y: p.y + v.y * d[i]
|
|
828
1303
|
})));
|
|
829
1304
|
}
|
|
830
|
-
scale(
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
if (
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
return
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
1305
|
+
scale(d) {
|
|
1306
|
+
const order = this.order;
|
|
1307
|
+
let distanceFn = false;
|
|
1308
|
+
if (typeof d === "function") distanceFn = d;
|
|
1309
|
+
if (distanceFn && order === 2) return this.raise().scale(distanceFn);
|
|
1310
|
+
const clockwise = this.clockwise;
|
|
1311
|
+
const points = this.points;
|
|
1312
|
+
if (this._linear) return this.translate(this.normal(0), distanceFn ? distanceFn(0) : d, distanceFn ? distanceFn(1) : d);
|
|
1313
|
+
const r1 = distanceFn ? distanceFn(0) : d;
|
|
1314
|
+
const r2 = distanceFn ? distanceFn(1) : d;
|
|
1315
|
+
const v = [this.offset(0, 10), this.offset(1, 10)];
|
|
1316
|
+
const np = [];
|
|
1317
|
+
const o = utils.lli4(v[0], v[0].c, v[1], v[1].c);
|
|
1318
|
+
if (!o) throw new Error("cannot scale this curve. Try reducing it first.");
|
|
1319
|
+
[0, 1].forEach(function(t) {
|
|
1320
|
+
const p = np[t * order] = utils.copy(points[t * order]);
|
|
1321
|
+
p.x += (t ? r2 : r1) * v[t].n.x;
|
|
1322
|
+
p.y += (t ? r2 : r1) * v[t].n.y;
|
|
1323
|
+
});
|
|
1324
|
+
if (!distanceFn) {
|
|
1325
|
+
[0, 1].forEach((t) => {
|
|
1326
|
+
if (order === 2 && !!t) return;
|
|
1327
|
+
const p = np[t * order];
|
|
1328
|
+
const d = this.derivative(t);
|
|
1329
|
+
const p2 = {
|
|
1330
|
+
x: p.x + d.x,
|
|
1331
|
+
y: p.y + d.y
|
|
851
1332
|
};
|
|
1333
|
+
np[t + 1] = utils.lli4(p, p2, o, points[t + 1]);
|
|
1334
|
+
});
|
|
1335
|
+
return new Bezier(np);
|
|
1336
|
+
}
|
|
1337
|
+
[0, 1].forEach(function(t) {
|
|
1338
|
+
if (order === 2 && !!t) return;
|
|
1339
|
+
var p = points[t + 1];
|
|
1340
|
+
var ov = {
|
|
1341
|
+
x: p.x - o.x,
|
|
1342
|
+
y: p.y - o.y
|
|
1343
|
+
};
|
|
1344
|
+
var rc = distanceFn ? distanceFn((t + 1) / order) : d;
|
|
1345
|
+
if (distanceFn && !clockwise) rc = -rc;
|
|
1346
|
+
var m = sqrt(ov.x * ov.x + ov.y * ov.y);
|
|
1347
|
+
ov.x /= m;
|
|
1348
|
+
ov.y /= m;
|
|
1349
|
+
np[t + 1] = {
|
|
1350
|
+
x: p.x + rc * ov.x,
|
|
1351
|
+
y: p.y + rc * ov.y
|
|
1352
|
+
};
|
|
1353
|
+
});
|
|
1354
|
+
return new Bezier(np);
|
|
1355
|
+
}
|
|
1356
|
+
outline(d1, d2, d3, d4) {
|
|
1357
|
+
d2 = d2 === void 0 ? d1 : d2;
|
|
1358
|
+
if (this._linear) {
|
|
1359
|
+
const n = this.normal(0);
|
|
1360
|
+
const start = this.points[0];
|
|
1361
|
+
const end = this.points[this.points.length - 1];
|
|
1362
|
+
let s;
|
|
1363
|
+
let mid;
|
|
1364
|
+
let e;
|
|
1365
|
+
if (d3 === void 0) {
|
|
1366
|
+
d3 = d1;
|
|
1367
|
+
d4 = d2;
|
|
852
1368
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
x: r.x + i.x,
|
|
857
|
-
y: r.y + i.y
|
|
1369
|
+
s = {
|
|
1370
|
+
x: start.x + n.x * d1,
|
|
1371
|
+
y: start.y + n.y * d1
|
|
858
1372
|
};
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
outline(e, n, r, i) {
|
|
863
|
-
if (n = n === void 0 ? e : n, this._linear) {
|
|
864
|
-
let a = this.normal(0), o = this.points[0], s = this.points[this.points.length - 1], c, l, u;
|
|
865
|
-
r === void 0 && (r = e, i = n), c = {
|
|
866
|
-
x: o.x + a.x * e,
|
|
867
|
-
y: o.y + a.y * e
|
|
868
|
-
}, u = {
|
|
869
|
-
x: s.x + a.x * r,
|
|
870
|
-
y: s.y + a.y * r
|
|
871
|
-
}, l = {
|
|
872
|
-
x: (c.x + u.x) / 2,
|
|
873
|
-
y: (c.y + u.y) / 2
|
|
1373
|
+
e = {
|
|
1374
|
+
x: end.x + n.x * d3,
|
|
1375
|
+
y: end.y + n.y * d3
|
|
874
1376
|
};
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1377
|
+
mid = {
|
|
1378
|
+
x: (s.x + e.x) / 2,
|
|
1379
|
+
y: (s.y + e.y) / 2
|
|
1380
|
+
};
|
|
1381
|
+
const fline = [
|
|
1382
|
+
s,
|
|
1383
|
+
mid,
|
|
1384
|
+
e
|
|
879
1385
|
];
|
|
880
|
-
|
|
881
|
-
x:
|
|
882
|
-
y:
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
x: (c.x + u.x) / 2,
|
|
888
|
-
y: (c.y + u.y) / 2
|
|
1386
|
+
s = {
|
|
1387
|
+
x: start.x - n.x * d2,
|
|
1388
|
+
y: start.y - n.y * d2
|
|
1389
|
+
};
|
|
1390
|
+
e = {
|
|
1391
|
+
x: end.x - n.x * d4,
|
|
1392
|
+
y: end.y - n.y * d4
|
|
889
1393
|
};
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1394
|
+
mid = {
|
|
1395
|
+
x: (s.x + e.x) / 2,
|
|
1396
|
+
y: (s.y + e.y) / 2
|
|
1397
|
+
};
|
|
1398
|
+
const bline = [
|
|
1399
|
+
e,
|
|
1400
|
+
mid,
|
|
1401
|
+
s
|
|
1402
|
+
];
|
|
1403
|
+
const ls = utils.makeline(bline[2], fline[0]);
|
|
1404
|
+
const le = utils.makeline(fline[2], bline[0]);
|
|
1405
|
+
return new PolyBezier([
|
|
1406
|
+
ls,
|
|
1407
|
+
new Bezier(fline),
|
|
1408
|
+
le,
|
|
1409
|
+
new Bezier(bline)
|
|
900
1410
|
]);
|
|
901
1411
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1412
|
+
const reduced = this.reduce();
|
|
1413
|
+
const len = reduced.length;
|
|
1414
|
+
const fcurves = [];
|
|
1415
|
+
let bcurves = [];
|
|
1416
|
+
let p;
|
|
1417
|
+
let alen = 0;
|
|
1418
|
+
let tlen = this.length();
|
|
1419
|
+
const graduated = typeof d3 !== "undefined" && typeof d4 !== "undefined";
|
|
1420
|
+
function linearDistanceFunction(s, e, tlen, alen, slen) {
|
|
1421
|
+
return function(v) {
|
|
1422
|
+
const f1 = alen / tlen;
|
|
1423
|
+
const f2 = (alen + slen) / tlen;
|
|
1424
|
+
const d = e - s;
|
|
1425
|
+
return utils.map(v, 0, 1, s + f1 * d, s + f2 * d);
|
|
907
1426
|
};
|
|
908
1427
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
]
|
|
1428
|
+
reduced.forEach(function(segment) {
|
|
1429
|
+
const slen = segment.length();
|
|
1430
|
+
if (graduated) {
|
|
1431
|
+
fcurves.push(segment.scale(linearDistanceFunction(d1, d3, tlen, alen, slen)));
|
|
1432
|
+
bcurves.push(segment.scale(linearDistanceFunction(-d2, -d4, tlen, alen, slen)));
|
|
1433
|
+
} else {
|
|
1434
|
+
fcurves.push(segment.scale(d1));
|
|
1435
|
+
bcurves.push(segment.scale(-d2));
|
|
1436
|
+
}
|
|
1437
|
+
alen += slen;
|
|
1438
|
+
});
|
|
1439
|
+
bcurves = bcurves.map(function(s) {
|
|
1440
|
+
p = s.points;
|
|
1441
|
+
if (p[3]) s.points = [
|
|
1442
|
+
p[3],
|
|
1443
|
+
p[2],
|
|
1444
|
+
p[1],
|
|
1445
|
+
p[0]
|
|
1446
|
+
];
|
|
1447
|
+
else s.points = [
|
|
1448
|
+
p[2],
|
|
1449
|
+
p[1],
|
|
1450
|
+
p[0]
|
|
1451
|
+
];
|
|
1452
|
+
return s;
|
|
923
1453
|
}).reverse();
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1454
|
+
const fs = fcurves[0].points[0];
|
|
1455
|
+
const fe = fcurves[len - 1].points[fcurves[len - 1].points.length - 1];
|
|
1456
|
+
const bs = bcurves[len - 1].points[bcurves[len - 1].points.length - 1];
|
|
1457
|
+
const be = bcurves[0].points[0];
|
|
1458
|
+
const ls = utils.makeline(bs, fs);
|
|
1459
|
+
const le = utils.makeline(fe, be);
|
|
1460
|
+
return new PolyBezier([ls].concat(fcurves).concat([le]).concat(bcurves));
|
|
1461
|
+
}
|
|
1462
|
+
outlineshapes(d1, d2, curveIntersectionThreshold) {
|
|
1463
|
+
d2 = d2 || d1;
|
|
1464
|
+
const outline = this.outline(d1, d2).curves;
|
|
1465
|
+
const shapes = [];
|
|
1466
|
+
for (let i = 1, len = outline.length; i < len / 2; i++) {
|
|
1467
|
+
const shape = utils.makeshape(outline[i], outline[len - i], curveIntersectionThreshold);
|
|
1468
|
+
shape.startcap.virtual = i > 1;
|
|
1469
|
+
shape.endcap.virtual = i < len / 2 - 1;
|
|
1470
|
+
shapes.push(shape);
|
|
1471
|
+
}
|
|
1472
|
+
return shapes;
|
|
1473
|
+
}
|
|
1474
|
+
intersects(curve, curveIntersectionThreshold) {
|
|
1475
|
+
if (!curve) return this.selfintersects(curveIntersectionThreshold);
|
|
1476
|
+
if (curve.p1 && curve.p2) return this.lineIntersects(curve);
|
|
1477
|
+
if (curve instanceof Bezier) curve = curve.reduce();
|
|
1478
|
+
return this.curveintersects(this.reduce(), curve, curveIntersectionThreshold);
|
|
1479
|
+
}
|
|
1480
|
+
lineIntersects(line) {
|
|
1481
|
+
const mx = min(line.p1.x, line.p2.x);
|
|
1482
|
+
const my = min(line.p1.y, line.p2.y);
|
|
1483
|
+
const MX = max(line.p1.x, line.p2.x);
|
|
1484
|
+
const MY = max(line.p1.y, line.p2.y);
|
|
1485
|
+
return utils.roots(this.points, line).filter((t) => {
|
|
1486
|
+
var p = this.get(t);
|
|
1487
|
+
return utils.between(p.x, mx, MX) && utils.between(p.y, my, MY);
|
|
944
1488
|
});
|
|
945
1489
|
}
|
|
946
|
-
selfintersects(
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1490
|
+
selfintersects(curveIntersectionThreshold) {
|
|
1491
|
+
const reduced = this.reduce();
|
|
1492
|
+
const len = reduced.length - 2;
|
|
1493
|
+
const results = [];
|
|
1494
|
+
for (let i = 0, result, left, right; i < len; i++) {
|
|
1495
|
+
left = reduced.slice(i, i + 1);
|
|
1496
|
+
right = reduced.slice(i + 2);
|
|
1497
|
+
result = this.curveintersects(left, right, curveIntersectionThreshold);
|
|
1498
|
+
results.push(...result);
|
|
1499
|
+
}
|
|
1500
|
+
return results;
|
|
1501
|
+
}
|
|
1502
|
+
curveintersects(c1, c2, curveIntersectionThreshold) {
|
|
1503
|
+
const pairs = [];
|
|
1504
|
+
c1.forEach(function(l) {
|
|
1505
|
+
c2.forEach(function(r) {
|
|
1506
|
+
if (l.overlaps(r)) pairs.push({
|
|
1507
|
+
left: l,
|
|
1508
|
+
right: r
|
|
958
1509
|
});
|
|
959
1510
|
});
|
|
960
1511
|
});
|
|
961
|
-
let
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
})
|
|
1512
|
+
let intersections = [];
|
|
1513
|
+
pairs.forEach(function(pair) {
|
|
1514
|
+
const result = utils.pairiteration(pair.left, pair.right, curveIntersectionThreshold);
|
|
1515
|
+
if (result.length > 0) intersections = intersections.concat(result);
|
|
1516
|
+
});
|
|
1517
|
+
return intersections;
|
|
966
1518
|
}
|
|
967
|
-
arcs(
|
|
968
|
-
|
|
1519
|
+
arcs(errorThreshold) {
|
|
1520
|
+
errorThreshold = errorThreshold || .5;
|
|
1521
|
+
return this._iterate(errorThreshold, []);
|
|
969
1522
|
}
|
|
970
|
-
_error(
|
|
971
|
-
|
|
972
|
-
|
|
1523
|
+
_error(pc, np1, s, e) {
|
|
1524
|
+
const q = (e - s) / 4;
|
|
1525
|
+
const c1 = this.get(s + q);
|
|
1526
|
+
const c2 = this.get(e - q);
|
|
1527
|
+
const ref = utils.dist(pc, np1);
|
|
1528
|
+
const d1 = utils.dist(pc, c1);
|
|
1529
|
+
const d2 = utils.dist(pc, c2);
|
|
1530
|
+
return abs(d1 - ref) + abs(d2 - ref);
|
|
973
1531
|
}
|
|
974
|
-
_iterate(
|
|
975
|
-
let
|
|
1532
|
+
_iterate(errorThreshold, circles) {
|
|
1533
|
+
let t_s = 0;
|
|
1534
|
+
let t_e = 1;
|
|
1535
|
+
let safety;
|
|
976
1536
|
do {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1537
|
+
safety = 0;
|
|
1538
|
+
t_e = 1;
|
|
1539
|
+
let np1 = this.get(t_s);
|
|
1540
|
+
let np2;
|
|
1541
|
+
let np3;
|
|
1542
|
+
let arc;
|
|
1543
|
+
let prev_arc;
|
|
1544
|
+
let curr_good = false;
|
|
1545
|
+
let prev_good = false;
|
|
1546
|
+
let done;
|
|
1547
|
+
let t_m = t_e;
|
|
1548
|
+
let prev_e = 1;
|
|
1549
|
+
let step = 0;
|
|
1550
|
+
do {
|
|
1551
|
+
prev_good = curr_good;
|
|
1552
|
+
prev_arc = arc;
|
|
1553
|
+
t_m = (t_s + t_e) / 2;
|
|
1554
|
+
step++;
|
|
1555
|
+
np2 = this.get(t_m);
|
|
1556
|
+
np3 = this.get(t_e);
|
|
1557
|
+
arc = utils.getccenter(np1, np2, np3);
|
|
1558
|
+
arc.interval = {
|
|
1559
|
+
start: t_s,
|
|
1560
|
+
end: t_e
|
|
1561
|
+
};
|
|
1562
|
+
curr_good = this._error(arc, np1, t_s, t_e) <= errorThreshold;
|
|
1563
|
+
done = prev_good && !curr_good;
|
|
1564
|
+
if (!done) prev_e = t_e;
|
|
1565
|
+
if (curr_good) {
|
|
1566
|
+
if (t_e >= 1) {
|
|
1567
|
+
arc.interval.end = prev_e = 1;
|
|
1568
|
+
prev_arc = arc;
|
|
1569
|
+
if (t_e > 1) {
|
|
1570
|
+
let d = {
|
|
1571
|
+
x: arc.x + arc.r * cos(arc.e),
|
|
1572
|
+
y: arc.y + arc.r * sin(arc.e)
|
|
989
1573
|
};
|
|
990
|
-
|
|
991
|
-
x:
|
|
992
|
-
y:
|
|
993
|
-
},
|
|
1574
|
+
arc.e += utils.angle({
|
|
1575
|
+
x: arc.x,
|
|
1576
|
+
y: arc.y
|
|
1577
|
+
}, d, this.get(1));
|
|
994
1578
|
}
|
|
995
1579
|
break;
|
|
996
1580
|
}
|
|
997
|
-
|
|
998
|
-
} else
|
|
999
|
-
while (!
|
|
1000
|
-
if (
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1581
|
+
t_e = t_e + (t_e - t_s) / 2;
|
|
1582
|
+
} else t_e = t_m;
|
|
1583
|
+
} while (!done && safety++ < 100);
|
|
1584
|
+
if (safety >= 100) break;
|
|
1585
|
+
prev_arc = prev_arc ? prev_arc : arc;
|
|
1586
|
+
circles.push(prev_arc);
|
|
1587
|
+
t_s = prev_e;
|
|
1588
|
+
} while (t_e < 1);
|
|
1589
|
+
return circles;
|
|
1004
1590
|
}
|
|
1005
1591
|
};
|
|
1006
1592
|
//#endregion
|
|
1007
|
-
export {
|
|
1593
|
+
export { Bezier as t };
|