1:
37:
38:
39: package ;
40:
41:
42: import ;
43: import ;
44:
45:
53: public class QuadSegment extends Segment
54: {
55: public Point2D cp;
56:
57:
61: public QuadSegment(double x1, double y1, double cx, double cy, double x2,
62: double y2)
63: {
64: super();
65: P1 = new Point2D.Double(x1, y1);
66: P2 = new Point2D.Double(x2, y2);
67: cp = new Point2D.Double(cx, cy);
68: }
69:
70: public QuadSegment(Point2D p1, Point2D cp, Point2D p2)
71: {
72: super();
73: P1 = p1;
74: P2 = p2;
75: this.cp = cp;
76: }
77:
78: public QuadSegment(QuadCurve2D curve)
79: {
80: super();
81: P1 = curve.getP1();
82: P2 = curve.getP2();
83: this.cp = curve.getCtrlPt();
84: }
85:
86:
89: public Object clone()
90: {
91: QuadSegment segment = null;
92:
93: try
94: {
95: segment = (QuadSegment) super.clone();
96:
97: segment.P1 = (Point2D) P1.clone();
98: segment.P2 = (Point2D) P2.clone();
99: segment.cp = (Point2D) cp.clone();
100: }
101: catch (CloneNotSupportedException cnse)
102: {
103: InternalError ie = new InternalError();
104: ie.initCause(cnse);
105: throw ie;
106: }
107:
108: return segment;
109: }
110:
111:
115: public Segment[] getDisplacedSegments(double radius)
116: {
117: this.radius = radius;
118: double x0 = P1.getX();
119: double y0 = P1.getY();
120: double x1 = cp.getX();
121: double y1 = cp.getY();
122: double x2 = P2.getX();
123: double y2 = P2.getY();
124:
125: QuadCurve2D left = new QuadCurve2D.Double();
126: QuadCurve2D right = new QuadCurve2D.Double();
127: QuadCurve2D orig = new QuadCurve2D.Double(x0, y0, x1, y1, x2, y2);
128: orig.subdivide(left, right);
129:
130: QuadSegment s1 = offsetSubdivided(left, true);
131: QuadSegment s2 = offsetSubdivided(left, false);
132:
133: s1.add( offsetSubdivided(right, true) );
134: s2.add( offsetSubdivided(right, false) );
135:
136: return new Segment[]{s1, s2};
137: }
138:
139: private QuadSegment offsetSubdivided(QuadCurve2D curve, boolean plus)
140: {
141: double[] n1 = normal(curve.getX1(), curve.getY1(),
142: curve.getCtrlX(), curve.getCtrlY());
143: double[] n2 = normal(curve.getCtrlX(), curve.getCtrlY(),
144: curve.getX2(), curve.getY2());
145:
146: Point2D cp;
147: QuadSegment s;
148: if(!plus)
149: {
150: n1[0] = -n1[0];
151: n1[1] = -n1[1];
152: n2[0] = -n2[0];
153: n2[1] = -n2[1];
154: }
155:
156:
157:
158: if (curve.getP1().equals(curve.getCtrlPt()))
159: {
160: cp = curve.getCtrlPt();
161: cp.setLocation(cp.getX() + n2[0], cp.getY() + n2[1]);
162: n1[0] = n2[0];
163: n1[1] = n2[1];
164: }
165: else if (curve.getP2().equals(curve.getCtrlPt()))
166: {
167: cp = curve.getCtrlPt();
168: cp.setLocation(cp.getX() + n1[0], cp.getY() + n1[1]);
169: n2[0] = n1[0];
170: n2[1] = n1[1];
171: }
172: else if (curve.getP1().equals(curve.getP2()))
173: {
174: cp = curve.getCtrlPt();
175:
176: double deltaX = curve.getX1() - curve.getCtrlX();
177: double deltaY = curve.getY1() - curve.getCtrlY();
178: double length = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
179: double ratio = radius / length;
180: deltaX *= ratio;
181: deltaY *= ratio;
182:
183: if (plus)
184: cp.setLocation(cp.getX() + deltaX, cp.getY() + deltaY);
185: else
186: cp.setLocation(cp.getX() - deltaX, cp.getY() - deltaY);
187: }
188: else if (n1[0] == n2[0] && n1[1] == n2[1])
189: {
190: cp = curve.getCtrlPt();
191: cp.setLocation(cp.getX() + n1[0], cp.getY() + n1[1]);
192: }
193: else
194: {
195: cp = lineIntersection(curve.getX1() + n1[0],
196: curve.getY1() + n1[1],
197: curve.getCtrlX() + n1[0],
198: curve.getCtrlY() + n1[1],
199: curve.getCtrlX() + n2[0],
200: curve.getCtrlY() + n2[1],
201: curve.getX2() + n2[0],
202: curve.getY2() + n2[1], true);
203: }
204:
205: s = new QuadSegment(curve.getX1() + n1[0], curve.getY1() + n1[1],
206: cp.getX(), cp.getY(),
207: curve.getX2() + n2[0], curve.getY2() + n2[1]);
208:
209: return s;
210: }
211:
212: private Point2D lineIntersection(double X1, double Y1,
213: double X2, double Y2,
214: double X3, double Y3,
215: double X4, double Y4,
216: boolean infinite)
217: {
218: double x1 = X1;
219: double y1 = Y1;
220: double rx = X2 - x1;
221: double ry = Y2 - y1;
222:
223: double x2 = X3;
224: double y2 = Y3;
225: double sx = X4 - x2;
226: double sy = Y4 - y2;
227:
228: double determinant = sx * ry - sy * rx;
229: double nom = (sx * (y2 - y1) + sy * (x1 - x2));
230:
231:
232: if (Math.abs(determinant) < 1E-6)
233: return null;
234:
235: nom = nom / determinant;
236:
237:
238: if(!infinite && (nom > 1.0 || nom < 0.0))
239: return null;
240:
241: return new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
242: }
243:
244: public void reverse()
245: {
246: Point2D p = P1;
247: P1 = P2;
248: P2 = p;
249: }
250:
251: public double[] cp1()
252: {
253: return new double[]{cp.getX(), cp.getY()};
254: }
255:
256: public double[] cp2()
257: {
258: return new double[]{cp.getX(), cp.getY()};
259: }
260: }