1 /*
2 * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
30 import java.awt.geom.QuadCurve2D;
31 import java.util.Vector;
32
33 final class Order2 extends Curve {
34 private double x0;
35 private double y0;
36 private double cx0;
37 private double cy0;
38 private double x1;
39 private double y1;
40 private double xmin;
41 private double xmax;
42
43 private double xcoeff0;
44 private double xcoeff1;
45 private double xcoeff2;
46 private double ycoeff0;
47 private double ycoeff1;
48 private double ycoeff2;
49
50 public static void insert(Vector<Curve> curves, double tmp[],
51 double x0, double y0,
52 double cx0, double cy0,
53 double x1, double y1,
54 int direction)
55 {
56 int numparams = getHorizontalParams(y0, cy0, y1, tmp);
57 if (numparams == 0) {
58 // We are using addInstance here to avoid inserting horisontal
59 // segments
60 addInstance(curves, x0, y0, cx0, cy0, x1, y1, direction);
61 return;
62 }
63 // assert(numparams == 1);
64 double t = tmp[0];
65 tmp[0] = x0; tmp[1] = y0;
66 tmp[2] = cx0; tmp[3] = cy0;
67 tmp[4] = x1; tmp[5] = y1;
68 split(tmp, 0, t);
69 int i0 = (direction == INCREASING)? 0 : 4;
70 int i1 = 4 - i0;
92 * horizontal sections into the specified {@code ret} array.
93 * <p>
94 * If we examine the parametric equation in t, we have:
95 * Py(t) = C0*(1-t)^2 + 2*CP*t*(1-t) + C1*t^2
96 * = C0 - 2*C0*t + C0*t^2 + 2*CP*t - 2*CP*t^2 + C1*t^2
97 * = C0 + (2*CP - 2*C0)*t + (C0 - 2*CP + C1)*t^2
98 * Py(t) = (C0 - 2*CP + C1)*t^2 + (2*CP - 2*C0)*t + (C0)
99 * If we take the derivative, we get:
100 * Py(t) = At^2 + Bt + C
101 * dPy(t) = 2At + B = 0
102 * 2*(C0 - 2*CP + C1)t + 2*(CP - C0) = 0
103 * 2*(C0 - 2*CP + C1)t = 2*(C0 - CP)
104 * t = 2*(C0 - CP) / 2*(C0 - 2*CP + C1)
105 * t = (C0 - CP) / (C0 - CP + C1 - CP)
106 * Note that this method will return 0 if the equation is a line,
107 * which is either always horizontal or never horizontal.
108 * Completely horizontal curves need to be eliminated by other
109 * means outside of this method.
110 */
111 public static int getHorizontalParams(double c0, double cp, double c1,
112 double ret[]) {
113 if (c0 <= cp && cp <= c1) {
114 return 0;
115 }
116 c0 -= cp;
117 c1 -= cp;
118 double denom = c0 + c1;
119 // If denom == 0 then cp == (c0+c1)/2 and we have a line.
120 if (denom == 0) {
121 return 0;
122 }
123 double t = c0 / denom;
124 // No splits at t==0 and t==1
125 if (t <= 0 || t >= 1) {
126 return 0;
127 }
128 ret[0] = t;
129 return 1;
130 }
131
132 /*
133 * Split the quadratic Bezier stored at coords[pos...pos+5] representing
134 * the paramtric range [0..1] into two subcurves representing the
135 * parametric subranges [0..t] and [t..1]. Store the results back
136 * into the array at coords[pos...pos+5] and coords[pos+4...pos+9].
137 */
138 public static void split(double coords[], int pos, double t) {
139 double x0, y0, cx, cy, x1, y1;
140 coords[pos+8] = x1 = coords[pos+4];
141 coords[pos+9] = y1 = coords[pos+5];
142 cx = coords[pos+2];
143 cy = coords[pos+3];
144 x1 = cx + (x1 - cx) * t;
145 y1 = cy + (y1 - cy) * t;
146 x0 = coords[pos+0];
147 y0 = coords[pos+1];
148 x0 = x0 + (cx - x0) * t;
149 y0 = y0 + (cy - y0) * t;
150 cx = x0 + (x1 - x0) * t;
151 cy = y0 + (y1 - y0) * t;
152 coords[pos+2] = x0;
153 coords[pos+3] = y0;
154 coords[pos+4] = cx;
155 coords[pos+5] = cy;
156 coords[pos+6] = x1;
157 coords[pos+7] = y1;
158 }
390 r.add(XforT(t), YforT(t));
391 }
392 r.add(x1, y1);
393 }
394
395 public Curve getSubCurve(double ystart, double yend, int dir) {
396 double t0, t1;
397 if (ystart <= y0) {
398 if (yend >= y1) {
399 return getWithDirection(dir);
400 }
401 t0 = 0;
402 } else {
403 t0 = TforY(ystart, ycoeff0, ycoeff1, ycoeff2);
404 }
405 if (yend >= y1) {
406 t1 = 1;
407 } else {
408 t1 = TforY(yend, ycoeff0, ycoeff1, ycoeff2);
409 }
410 double eqn[] = new double[10];
411 eqn[0] = x0;
412 eqn[1] = y0;
413 eqn[2] = cx0;
414 eqn[3] = cy0;
415 eqn[4] = x1;
416 eqn[5] = y1;
417 if (t1 < 1) {
418 split(eqn, 0, t1);
419 }
420 int i;
421 if (t0 <= 0) {
422 i = 0;
423 } else {
424 split(eqn, 0, t0 / t1);
425 i = 4;
426 }
427 return new Order2(eqn[i+0], ystart,
428 eqn[i+2], eqn[i+3],
429 eqn[i+4], yend,
430 dir);
431 }
432
433 public Curve getReversedCurve() {
434 return new Order2(x0, y0, cx0, cy0, x1, y1, -direction);
435 }
436
437 public int getSegment(double coords[]) {
438 coords[0] = cx0;
439 coords[1] = cy0;
440 if (direction == INCREASING) {
441 coords[2] = x1;
442 coords[3] = y1;
443 } else {
444 coords[2] = x0;
445 coords[3] = y0;
446 }
447 return PathIterator.SEG_QUADTO;
448 }
449
450 public String controlPointString() {
451 return ("("+round(cx0)+", "+round(cy0)+"), ");
452 }
453 }
|
1 /*
2 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
30 import java.awt.geom.QuadCurve2D;
31 import java.util.Vector;
32
33 final class Order2 extends Curve {
34 private double x0;
35 private double y0;
36 private double cx0;
37 private double cy0;
38 private double x1;
39 private double y1;
40 private double xmin;
41 private double xmax;
42
43 private double xcoeff0;
44 private double xcoeff1;
45 private double xcoeff2;
46 private double ycoeff0;
47 private double ycoeff1;
48 private double ycoeff2;
49
50 public static void insert(Vector<Curve> curves, double[] tmp,
51 double x0, double y0,
52 double cx0, double cy0,
53 double x1, double y1,
54 int direction)
55 {
56 int numparams = getHorizontalParams(y0, cy0, y1, tmp);
57 if (numparams == 0) {
58 // We are using addInstance here to avoid inserting horisontal
59 // segments
60 addInstance(curves, x0, y0, cx0, cy0, x1, y1, direction);
61 return;
62 }
63 // assert(numparams == 1);
64 double t = tmp[0];
65 tmp[0] = x0; tmp[1] = y0;
66 tmp[2] = cx0; tmp[3] = cy0;
67 tmp[4] = x1; tmp[5] = y1;
68 split(tmp, 0, t);
69 int i0 = (direction == INCREASING)? 0 : 4;
70 int i1 = 4 - i0;
92 * horizontal sections into the specified {@code ret} array.
93 * <p>
94 * If we examine the parametric equation in t, we have:
95 * Py(t) = C0*(1-t)^2 + 2*CP*t*(1-t) + C1*t^2
96 * = C0 - 2*C0*t + C0*t^2 + 2*CP*t - 2*CP*t^2 + C1*t^2
97 * = C0 + (2*CP - 2*C0)*t + (C0 - 2*CP + C1)*t^2
98 * Py(t) = (C0 - 2*CP + C1)*t^2 + (2*CP - 2*C0)*t + (C0)
99 * If we take the derivative, we get:
100 * Py(t) = At^2 + Bt + C
101 * dPy(t) = 2At + B = 0
102 * 2*(C0 - 2*CP + C1)t + 2*(CP - C0) = 0
103 * 2*(C0 - 2*CP + C1)t = 2*(C0 - CP)
104 * t = 2*(C0 - CP) / 2*(C0 - 2*CP + C1)
105 * t = (C0 - CP) / (C0 - CP + C1 - CP)
106 * Note that this method will return 0 if the equation is a line,
107 * which is either always horizontal or never horizontal.
108 * Completely horizontal curves need to be eliminated by other
109 * means outside of this method.
110 */
111 public static int getHorizontalParams(double c0, double cp, double c1,
112 double[] ret) {
113 if (c0 <= cp && cp <= c1) {
114 return 0;
115 }
116 c0 -= cp;
117 c1 -= cp;
118 double denom = c0 + c1;
119 // If denom == 0 then cp == (c0+c1)/2 and we have a line.
120 if (denom == 0) {
121 return 0;
122 }
123 double t = c0 / denom;
124 // No splits at t==0 and t==1
125 if (t <= 0 || t >= 1) {
126 return 0;
127 }
128 ret[0] = t;
129 return 1;
130 }
131
132 /*
133 * Split the quadratic Bezier stored at coords[pos...pos+5] representing
134 * the paramtric range [0..1] into two subcurves representing the
135 * parametric subranges [0..t] and [t..1]. Store the results back
136 * into the array at coords[pos...pos+5] and coords[pos+4...pos+9].
137 */
138 public static void split(double[] coords, int pos, double t) {
139 double x0, y0, cx, cy, x1, y1;
140 coords[pos+8] = x1 = coords[pos+4];
141 coords[pos+9] = y1 = coords[pos+5];
142 cx = coords[pos+2];
143 cy = coords[pos+3];
144 x1 = cx + (x1 - cx) * t;
145 y1 = cy + (y1 - cy) * t;
146 x0 = coords[pos+0];
147 y0 = coords[pos+1];
148 x0 = x0 + (cx - x0) * t;
149 y0 = y0 + (cy - y0) * t;
150 cx = x0 + (x1 - x0) * t;
151 cy = y0 + (y1 - y0) * t;
152 coords[pos+2] = x0;
153 coords[pos+3] = y0;
154 coords[pos+4] = cx;
155 coords[pos+5] = cy;
156 coords[pos+6] = x1;
157 coords[pos+7] = y1;
158 }
390 r.add(XforT(t), YforT(t));
391 }
392 r.add(x1, y1);
393 }
394
395 public Curve getSubCurve(double ystart, double yend, int dir) {
396 double t0, t1;
397 if (ystart <= y0) {
398 if (yend >= y1) {
399 return getWithDirection(dir);
400 }
401 t0 = 0;
402 } else {
403 t0 = TforY(ystart, ycoeff0, ycoeff1, ycoeff2);
404 }
405 if (yend >= y1) {
406 t1 = 1;
407 } else {
408 t1 = TforY(yend, ycoeff0, ycoeff1, ycoeff2);
409 }
410 double[] eqn = new double[10];
411 eqn[0] = x0;
412 eqn[1] = y0;
413 eqn[2] = cx0;
414 eqn[3] = cy0;
415 eqn[4] = x1;
416 eqn[5] = y1;
417 if (t1 < 1) {
418 split(eqn, 0, t1);
419 }
420 int i;
421 if (t0 <= 0) {
422 i = 0;
423 } else {
424 split(eqn, 0, t0 / t1);
425 i = 4;
426 }
427 return new Order2(eqn[i+0], ystart,
428 eqn[i+2], eqn[i+3],
429 eqn[i+4], yend,
430 dir);
431 }
432
433 public Curve getReversedCurve() {
434 return new Order2(x0, y0, cx0, cy0, x1, y1, -direction);
435 }
436
437 public int getSegment(double[] coords) {
438 coords[0] = cx0;
439 coords[1] = cy0;
440 if (direction == INCREASING) {
441 coords[2] = x1;
442 coords[3] = y1;
443 } else {
444 coords[2] = x0;
445 coords[3] = y0;
446 }
447 return PathIterator.SEG_QUADTO;
448 }
449
450 public String controlPointString() {
451 return ("("+round(cx0)+", "+round(cy0)+"), ");
452 }
453 }
|