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: cp = lineIntersection(curve.getX1() + n1[0],
151: curve.getY1() + n1[1],
152: curve.getCtrlX() + n1[0],
153: curve.getCtrlY() + n1[1],
154: curve.getCtrlX() + n2[0],
155: curve.getCtrlY() + n2[1],
156: curve.getX2() + n2[0],
157: curve.getY2() + n2[1], true);
158: s = new QuadSegment(curve.getX1() + n1[0], curve.getY1() + n1[1],
159: cp.getX(), cp.getY(),
160: curve.getX2() + n2[0], curve.getY2() + n2[1]);
161: }
162: else
163: {
164: cp = lineIntersection(curve.getX1() - n1[0],
165: curve.getY1() - n1[1],
166: curve.getCtrlX() - n1[0],
167: curve.getCtrlY() - n1[1],
168: curve.getCtrlX() - n2[0],
169: curve.getCtrlY() - n2[1],
170: curve.getX2() - n2[0],
171: curve.getY2() - n2[1], true);
172:
173: s = new QuadSegment(curve.getX1() - n1[0], curve.getY1() - n1[1],
174: cp.getX(), cp.getY(),
175: curve.getX2() - n2[0], curve.getY2() - n2[1]);
176: }
177:
178: return s;
179: }
180:
181: private Point2D lineIntersection(double X1, double Y1,
182: double X2, double Y2,
183: double X3, double Y3,
184: double X4, double Y4,
185: boolean infinite)
186: {
187: double x1 = X1;
188: double y1 = Y1;
189: double rx = X2 - x1;
190: double ry = Y2 - y1;
191:
192: double x2 = X3;
193: double y2 = Y3;
194: double sx = X4 - x2;
195: double sy = Y4 - y2;
196:
197: double determinant = sx * ry - sy * rx;
198: double nom = (sx * (y2 - y1) + sy * (x1 - x2));
199:
200:
201: if (Math.abs(determinant) < 1E-6)
202: return null;
203:
204: nom = nom / determinant;
205:
206:
207: if(!infinite && (nom > 1.0 || nom < 0.0))
208: return null;
209:
210: return new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
211: }
212:
213: public void reverse()
214: {
215: Point2D p = P1;
216: P1 = P2;
217: P2 = p;
218: }
219:
220: public double[] cp1()
221: {
222: return new double[]{cp.getX(), cp.getY()};
223: }
224:
225: public double[] cp2()
226: {
227: return new double[]{cp.getX(), cp.getY()};
228: }
229: }