Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / site / j2s / jssun / awt / geom / Order3.js
1 Clazz.declarePackage ("jssun.awt.geom");
2 Clazz.load (["jssun.awt.geom.Curve"], "jssun.awt.geom.Order3", ["java.awt.geom.QuadCurve2D", "jssun.awt.geom.Order2"], function () {
3 c$ = Clazz.decorateAsClass (function () {
4 this.x0 = 0;
5 this.y0 = 0;
6 this.cx0 = 0;
7 this.cy0 = 0;
8 this.cx1 = 0;
9 this.cy1 = 0;
10 this.x1 = 0;
11 this.y1 = 0;
12 this.xmin = 0;
13 this.xmax = 0;
14 this.xcoeff0 = 0;
15 this.xcoeff1 = 0;
16 this.xcoeff2 = 0;
17 this.xcoeff3 = 0;
18 this.ycoeff0 = 0;
19 this.ycoeff1 = 0;
20 this.ycoeff2 = 0;
21 this.ycoeff3 = 0;
22 this.TforY1 = 0;
23 this.YforT1 = 0;
24 this.TforY2 = 0;
25 this.YforT2 = 0;
26 this.TforY3 = 0;
27 this.YforT3 = 0;
28 Clazz.instantialize (this, arguments);
29 }, jssun.awt.geom, "Order3", jssun.awt.geom.Curve);
30 c$.insert = Clazz.defineMethod (c$, "insert", 
31 function (curves, tmp, x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction) {
32 var numparams = jssun.awt.geom.Order3.getHorizontalParams (y0, cy0, cy1, y1, tmp);
33 if (numparams == 0) {
34 jssun.awt.geom.Order3.addInstance (curves, x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction);
35 return;
36 }tmp[3] = x0;
37 tmp[4] = y0;
38 tmp[5] = cx0;
39 tmp[6] = cy0;
40 tmp[7] = cx1;
41 tmp[8] = cy1;
42 tmp[9] = x1;
43 tmp[10] = y1;
44 var t = tmp[0];
45 if (numparams > 1 && t > tmp[1]) {
46 tmp[0] = tmp[1];
47 tmp[1] = t;
48 t = tmp[0];
49 }jssun.awt.geom.Order3.split (tmp, 3, t);
50 if (numparams > 1) {
51 t = (tmp[1] - t) / (1 - t);
52 jssun.awt.geom.Order3.split (tmp, 9, t);
53 }var index = 3;
54 if (direction == -1) {
55 index += numparams * 6;
56 }while (numparams >= 0) {
57 jssun.awt.geom.Order3.addInstance (curves, tmp[index + 0], tmp[index + 1], tmp[index + 2], tmp[index + 3], tmp[index + 4], tmp[index + 5], tmp[index + 6], tmp[index + 7], direction);
58 numparams--;
59 if (direction == 1) {
60 index += 6;
61 } else {
62 index -= 6;
63 }}
64 }, "java.util.Vector,~A,~N,~N,~N,~N,~N,~N,~N,~N,~N");
65 c$.addInstance = Clazz.defineMethod (c$, "addInstance", 
66 function (curves, x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction) {
67 if (y0 > y1) {
68 curves.add ( new jssun.awt.geom.Order3 (x1, y1, cx1, cy1, cx0, cy0, x0, y0, -direction));
69 } else if (y1 > y0) {
70 curves.add ( new jssun.awt.geom.Order3 (x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction));
71 }}, "java.util.Vector,~N,~N,~N,~N,~N,~N,~N,~N,~N");
72 c$.getHorizontalParams = Clazz.defineMethod (c$, "getHorizontalParams", 
73 function (c0, cp0, cp1, c1, ret) {
74 if (c0 <= cp0 && cp0 <= cp1 && cp1 <= c1) {
75 return 0;
76 }c1 -= cp1;
77 cp1 -= cp0;
78 cp0 -= c0;
79 ret[0] = cp0;
80 ret[1] = (cp1 - cp0) * 2;
81 ret[2] = (c1 - cp1 - cp1 + cp0);
82 var numroots = java.awt.geom.QuadCurve2D.solveQuadratic (ret, ret);
83 var j = 0;
84 for (var i = 0; i < numroots; i++) {
85 var t = ret[i];
86 if (t > 0 && t < 1) {
87 if (j < i) {
88 ret[j] = t;
89 }j++;
90 }}
91 return j;
92 }, "~N,~N,~N,~N,~A");
93 c$.split = Clazz.defineMethod (c$, "split", 
94 function (coords, pos, t) {
95 var x0;
96 var y0;
97 var cx0;
98 var cy0;
99 var cx1;
100 var cy1;
101 var x1;
102 var y1;
103 coords[pos + 12] = x1 = coords[pos + 6];
104 coords[pos + 13] = y1 = coords[pos + 7];
105 cx1 = coords[pos + 4];
106 cy1 = coords[pos + 5];
107 x1 = cx1 + (x1 - cx1) * t;
108 y1 = cy1 + (y1 - cy1) * t;
109 x0 = coords[pos + 0];
110 y0 = coords[pos + 1];
111 cx0 = coords[pos + 2];
112 cy0 = coords[pos + 3];
113 x0 = x0 + (cx0 - x0) * t;
114 y0 = y0 + (cy0 - y0) * t;
115 cx0 = cx0 + (cx1 - cx0) * t;
116 cy0 = cy0 + (cy1 - cy0) * t;
117 cx1 = cx0 + (x1 - cx0) * t;
118 cy1 = cy0 + (y1 - cy0) * t;
119 cx0 = x0 + (cx0 - x0) * t;
120 cy0 = y0 + (cy0 - y0) * t;
121 coords[pos + 2] = x0;
122 coords[pos + 3] = y0;
123 coords[pos + 4] = cx0;
124 coords[pos + 5] = cy0;
125 coords[pos + 6] = cx0 + (cx1 - cx0) * t;
126 coords[pos + 7] = cy0 + (cy1 - cy0) * t;
127 coords[pos + 8] = cx1;
128 coords[pos + 9] = cy1;
129 coords[pos + 10] = x1;
130 coords[pos + 11] = y1;
131 }, "~A,~N,~N");
132 Clazz.makeConstructor (c$, 
133 function (x0, y0, cx0, cy0, cx1, cy1, x1, y1, direction) {
134 Clazz.superConstructor (this, jssun.awt.geom.Order3, [direction]);
135 if (cy0 < y0) cy0 = y0;
136 if (cy1 > y1) cy1 = y1;
137 this.x0 = x0;
138 this.y0 = y0;
139 this.cx0 = cx0;
140 this.cy0 = cy0;
141 this.cx1 = cx1;
142 this.cy1 = cy1;
143 this.x1 = x1;
144 this.y1 = y1;
145 this.xmin = Math.min (Math.min (x0, x1), Math.min (cx0, cx1));
146 this.xmax = Math.max (Math.max (x0, x1), Math.max (cx0, cx1));
147 this.xcoeff0 = x0;
148 this.xcoeff1 = (cx0 - x0) * 3.0;
149 this.xcoeff2 = (cx1 - cx0 - cx0 + x0) * 3.0;
150 this.xcoeff3 = x1 - (cx1 - cx0) * 3.0 - x0;
151 this.ycoeff0 = y0;
152 this.ycoeff1 = (cy0 - y0) * 3.0;
153 this.ycoeff2 = (cy1 - cy0 - cy0 + y0) * 3.0;
154 this.ycoeff3 = y1 - (cy1 - cy0) * 3.0 - y0;
155 this.YforT1 = this.YforT2 = this.YforT3 = y0;
156 }, "~N,~N,~N,~N,~N,~N,~N,~N,~N");
157 Clazz.overrideMethod (c$, "getOrder", 
158 function () {
159 return 3;
160 });
161 Clazz.overrideMethod (c$, "getXTop", 
162 function () {
163 return this.x0;
164 });
165 Clazz.overrideMethod (c$, "getYTop", 
166 function () {
167 return this.y0;
168 });
169 Clazz.overrideMethod (c$, "getXBot", 
170 function () {
171 return this.x1;
172 });
173 Clazz.overrideMethod (c$, "getYBot", 
174 function () {
175 return this.y1;
176 });
177 Clazz.overrideMethod (c$, "getXMin", 
178 function () {
179 return this.xmin;
180 });
181 Clazz.overrideMethod (c$, "getXMax", 
182 function () {
183 return this.xmax;
184 });
185 Clazz.overrideMethod (c$, "getX0", 
186 function () {
187 return (this.direction == 1) ? this.x0 : this.x1;
188 });
189 Clazz.overrideMethod (c$, "getY0", 
190 function () {
191 return (this.direction == 1) ? this.y0 : this.y1;
192 });
193 Clazz.defineMethod (c$, "getCX0", 
194 function () {
195 return (this.direction == 1) ? this.cx0 : this.cx1;
196 });
197 Clazz.defineMethod (c$, "getCY0", 
198 function () {
199 return (this.direction == 1) ? this.cy0 : this.cy1;
200 });
201 Clazz.defineMethod (c$, "getCX1", 
202 function () {
203 return (this.direction == -1) ? this.cx0 : this.cx1;
204 });
205 Clazz.defineMethod (c$, "getCY1", 
206 function () {
207 return (this.direction == -1) ? this.cy0 : this.cy1;
208 });
209 Clazz.overrideMethod (c$, "getX1", 
210 function () {
211 return (this.direction == -1) ? this.x0 : this.x1;
212 });
213 Clazz.overrideMethod (c$, "getY1", 
214 function () {
215 return (this.direction == -1) ? this.y0 : this.y1;
216 });
217 Clazz.overrideMethod (c$, "TforY", 
218 function (y) {
219 if (y <= this.y0) return 0;
220 if (y >= this.y1) return 1;
221 if (y == this.YforT1) return this.TforY1;
222 if (y == this.YforT2) return this.TforY2;
223 if (y == this.YforT3) return this.TforY3;
224 if (this.ycoeff3 == 0.0) {
225 return jssun.awt.geom.Order2.TforY (y, this.ycoeff0, this.ycoeff1, this.ycoeff2);
226 }var a = this.ycoeff2 / this.ycoeff3;
227 var b = this.ycoeff1 / this.ycoeff3;
228 var c = (this.ycoeff0 - y) / this.ycoeff3;
229 var Q = (a * a - 3.0 * b) / 9.0;
230 var R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
231 var R2 = R * R;
232 var Q3 = Q * Q * Q;
233 var a_3 = a / 3.0;
234 var t;
235 if (R2 < Q3) {
236 var theta = Math.acos (R / Math.sqrt (Q3));
237 Q = -2.0 * Math.sqrt (Q);
238 t = this.refine (a, b, c, y, Q * Math.cos (theta / 3.0) - a_3);
239 if (t < 0) {
240 t = this.refine (a, b, c, y, Q * Math.cos ((theta + 6.283185307179586) / 3.0) - a_3);
241 }if (t < 0) {
242 t = this.refine (a, b, c, y, Q * Math.cos ((theta - 6.283185307179586) / 3.0) - a_3);
243 }} else {
244 var neg = (R < 0.0);
245 var S = Math.sqrt (R2 - Q3);
246 if (neg) {
247 R = -R;
248 }var A = Math.pow (R + S, 0.3333333333333333);
249 if (!neg) {
250 A = -A;
251 }var B = (A == 0.0) ? 0.0 : (Q / A);
252 t = this.refine (a, b, c, y, (A + B) - a_3);
253 }if (t < 0) {
254 var t0 = 0;
255 var t1 = 1;
256 while (true) {
257 t = (t0 + t1) / 2;
258 if (t == t0 || t == t1) {
259 break;
260 }var yt = this.YforT (t);
261 if (yt < y) {
262 t0 = t;
263 } else if (yt > y) {
264 t1 = t;
265 } else {
266 break;
267 }}
268 }if (t >= 0) {
269 this.TforY3 = this.TforY2;
270 this.YforT3 = this.YforT2;
271 this.TforY2 = this.TforY1;
272 this.YforT2 = this.YforT1;
273 this.TforY1 = t;
274 this.YforT1 = y;
275 }return t;
276 }, "~N");
277 Clazz.defineMethod (c$, "refine", 
278 function (a, b, c, target, t) {
279 if (t < -0.1 || t > 1.1) {
280 return -1;
281 }var y = this.YforT (t);
282 var t0;
283 var t1;
284 if (y < target) {
285 t0 = t;
286 t1 = 1;
287 } else {
288 t0 = 0;
289 t1 = t;
290 }var origt = t;
291 var origy = y;
292 var useslope = true;
293 while (y != target) {
294 if (!useslope) {
295 var t2 = (t0 + t1) / 2;
296 if (t2 == t0 || t2 == t1) {
297 break;
298 }t = t2;
299 } else {
300 var slope = this.dYforT (t, 1);
301 if (slope == 0) {
302 useslope = false;
303 continue;
304 }var t2 = t + ((target - y) / slope);
305 if (t2 == t || t2 <= t0 || t2 >= t1) {
306 useslope = false;
307 continue;
308 }t = t2;
309 }y = this.YforT (t);
310 if (y < target) {
311 t0 = t;
312 } else if (y > target) {
313 t1 = t;
314 } else {
315 break;
316 }}
317 var verbose = false;
318 if (false && t >= 0 && t <= 1) {
319 y = this.YforT (t);
320 var tdiff = jssun.awt.geom.Curve.diffbits (t, origt);
321 var ydiff = jssun.awt.geom.Curve.diffbits (y, origy);
322 var yerr = jssun.awt.geom.Curve.diffbits (y, target);
323 if (yerr > 0 || (verbose && tdiff > 0)) {
324 System.out.println ("target was y = " + target);
325 System.out.println ("original was y = " + origy + ", t = " + origt);
326 System.out.println ("final was y = " + y + ", t = " + t);
327 System.out.println ("t diff is " + tdiff);
328 System.out.println ("y diff is " + ydiff);
329 System.out.println ("y error is " + yerr);
330 var tlow = jssun.awt.geom.Curve.prev (t);
331 var ylow = this.YforT (tlow);
332 var thi = jssun.awt.geom.Curve.next (t);
333 var yhi = this.YforT (thi);
334 if (Math.abs (target - ylow) < Math.abs (target - y) || Math.abs (target - yhi) < Math.abs (target - y)) {
335 System.out.println ("adjacent y's = [" + ylow + ", " + yhi + "]");
336 }}}return (t > 1) ? -1 : t;
337 }, "~N,~N,~N,~N,~N");
338 Clazz.overrideMethod (c$, "XforY", 
339 function (y) {
340 if (y <= this.y0) {
341 return this.x0;
342 }if (y >= this.y1) {
343 return this.x1;
344 }return this.XforT (this.TforY (y));
345 }, "~N");
346 Clazz.overrideMethod (c$, "XforT", 
347 function (t) {
348 return (((this.xcoeff3 * t) + this.xcoeff2) * t + this.xcoeff1) * t + this.xcoeff0;
349 }, "~N");
350 Clazz.overrideMethod (c$, "YforT", 
351 function (t) {
352 return (((this.ycoeff3 * t) + this.ycoeff2) * t + this.ycoeff1) * t + this.ycoeff0;
353 }, "~N");
354 Clazz.overrideMethod (c$, "dXforT", 
355 function (t, deriv) {
356 switch (deriv) {
357 case 0:
358 return (((this.xcoeff3 * t) + this.xcoeff2) * t + this.xcoeff1) * t + this.xcoeff0;
359 case 1:
360 return ((3 * this.xcoeff3 * t) + 2 * this.xcoeff2) * t + this.xcoeff1;
361 case 2:
362 return (6 * this.xcoeff3 * t) + 2 * this.xcoeff2;
363 case 3:
364 return 6 * this.xcoeff3;
365 default:
366 return 0;
367 }
368 }, "~N,~N");
369 Clazz.overrideMethod (c$, "dYforT", 
370 function (t, deriv) {
371 switch (deriv) {
372 case 0:
373 return (((this.ycoeff3 * t) + this.ycoeff2) * t + this.ycoeff1) * t + this.ycoeff0;
374 case 1:
375 return ((3 * this.ycoeff3 * t) + 2 * this.ycoeff2) * t + this.ycoeff1;
376 case 2:
377 return (6 * this.ycoeff3 * t) + 2 * this.ycoeff2;
378 case 3:
379 return 6 * this.ycoeff3;
380 default:
381 return 0;
382 }
383 }, "~N,~N");
384 Clazz.overrideMethod (c$, "nextVertical", 
385 function (t0, t1) {
386 var eqn =  Clazz.newDoubleArray (-1, [this.xcoeff1, 2 * this.xcoeff2, 3 * this.xcoeff3]);
387 var numroots = java.awt.geom.QuadCurve2D.solveQuadratic (eqn, eqn);
388 for (var i = 0; i < numroots; i++) {
389 if (eqn[i] > t0 && eqn[i] < t1) {
390 t1 = eqn[i];
391 }}
392 return t1;
393 }, "~N,~N");
394 Clazz.overrideMethod (c$, "enlarge", 
395 function (r) {
396 r.add (this.x0, this.y0);
397 var eqn =  Clazz.newDoubleArray (-1, [this.xcoeff1, 2 * this.xcoeff2, 3 * this.xcoeff3]);
398 var numroots = java.awt.geom.QuadCurve2D.solveQuadratic (eqn, eqn);
399 for (var i = 0; i < numroots; i++) {
400 var t = eqn[i];
401 if (t > 0 && t < 1) {
402 r.add (this.XforT (t), this.YforT (t));
403 }}
404 r.add (this.x1, this.y1);
405 }, "java.awt.geom.Rectangle2D");
406 Clazz.defineMethod (c$, "getSubCurve", 
407 function (ystart, yend, dir) {
408 if (ystart <= this.y0 && yend >= this.y1) {
409 return this.getWithDirection (dir);
410 }var eqn =  Clazz.newDoubleArray (14, 0);
411 var t0;
412 var t1;
413 t0 = this.TforY (ystart);
414 t1 = this.TforY (yend);
415 eqn[0] = this.x0;
416 eqn[1] = this.y0;
417 eqn[2] = this.cx0;
418 eqn[3] = this.cy0;
419 eqn[4] = this.cx1;
420 eqn[5] = this.cy1;
421 eqn[6] = this.x1;
422 eqn[7] = this.y1;
423 if (t0 > t1) {
424 var t = t0;
425 t0 = t1;
426 t1 = t;
427 }if (t1 < 1) {
428 jssun.awt.geom.Order3.split (eqn, 0, t1);
429 }var i;
430 if (t0 <= 0) {
431 i = 0;
432 } else {
433 jssun.awt.geom.Order3.split (eqn, 0, t0 / t1);
434 i = 6;
435 }return  new jssun.awt.geom.Order3 (eqn[i + 0], ystart, eqn[i + 2], eqn[i + 3], eqn[i + 4], eqn[i + 5], eqn[i + 6], yend, dir);
436 }, "~N,~N,~N");
437 Clazz.overrideMethod (c$, "getReversedCurve", 
438 function () {
439 return  new jssun.awt.geom.Order3 (this.x0, this.y0, this.cx0, this.cy0, this.cx1, this.cy1, this.x1, this.y1, -this.direction);
440 });
441 Clazz.overrideMethod (c$, "getSegment", 
442 function (coords) {
443 if (this.direction == 1) {
444 coords[0] = this.cx0;
445 coords[1] = this.cy0;
446 coords[2] = this.cx1;
447 coords[3] = this.cy1;
448 coords[4] = this.x1;
449 coords[5] = this.y1;
450 } else {
451 coords[0] = this.cx1;
452 coords[1] = this.cy1;
453 coords[2] = this.cx0;
454 coords[3] = this.cy0;
455 coords[4] = this.x0;
456 coords[5] = this.y0;
457 }return 3;
458 }, "~A");
459 Clazz.overrideMethod (c$, "controlPointString", 
460 function () {
461 return (("(" + jssun.awt.geom.Curve.round (this.getCX0 ()) + ", " + jssun.awt.geom.Curve.round (this.getCY0 ()) + "), ") + ("(" + jssun.awt.geom.Curve.round (this.getCX1 ()) + ", " + jssun.awt.geom.Curve.round (this.getCY1 ()) + "), "));
462 });
463 });