1
2 package math.geom2d.conic;
3
4 import java.util.ArrayList;
5 import java.util.Collection;
6
7 import math.geom2d.AffineTransform2D;
8 import math.geom2d.Box2D;
9 import math.geom2d.Point2D;
10 import math.geom2d.Shape2D;
11 import math.geom2d.UnboundedShapeException;
12 import math.geom2d.Vector2D;
13 import math.geom2d.curve.AbstractSmoothCurve2D;
14 import math.geom2d.curve.Curve2D;
15 import math.geom2d.curve.Curve2DUtils;
16 import math.geom2d.curve.CurveArray2D;
17 import math.geom2d.curve.CurveSet2D;
18 import math.geom2d.curve.SmoothCurve2D;
19 import math.geom2d.domain.SmoothOrientedCurve2D;
20 import math.geom2d.line.LinearShape2D;
21
22
23
24
25
26
27
28 public class HyperbolaBranchArc2D extends AbstractSmoothCurve2D
29 implements SmoothOrientedCurve2D, Cloneable {
30
31
32 HyperbolaBranch2D branch = null;
33
34 double t0 = 0;
35 double t1 = 1;
36
37 public HyperbolaBranchArc2D(HyperbolaBranch2D branch, double t0, double t1) {
38 this.branch = branch;
39 this.t0 = t0;
40 this.t1 = t1;
41 }
42
43
44
45
46 public HyperbolaBranch2D getHyperbolaBranch() {
47 return branch;
48 }
49
50
51
52
53 public double getCurvature(double t) {
54 return branch.getCurvature(t);
55 }
56
57 public Vector2D getTangent(double t) {
58 return branch.getTangent(t);
59 }
60
61
62
63
64 public double getSignedDistance(java.awt.geom.Point2D point) {
65 return this.getSignedDistance(point.getX(), point.getY());
66 }
67
68 public double getSignedDistance(double x, double y) {
69
70 return 0;
71 }
72
73 public double getWindingAngle(java.awt.geom.Point2D point) {
74
75 return 0;
76 }
77
78 public boolean isInside(java.awt.geom.Point2D pt) {
79
80 return false;
81 }
82
83
84
85
86 public java.awt.geom.GeneralPath appendPath(java.awt.geom.GeneralPath path) {
87 return this.getAsPolyline(60).appendPath(path);
88 }
89
90
91 public boolean isClosed() {
92 return false;
93 }
94
95
96
97
98 public Collection<Point2D> getIntersections(LinearShape2D line) {
99 Collection<Point2D> inters0 = this.branch.getIntersections(line);
100 ArrayList<Point2D> inters = new ArrayList<Point2D>();
101 for (Point2D point : inters0) {
102 double pos = this.branch.project(point);
103 if (pos>this.t0&&pos<this.t1)
104 inters.add(point);
105 }
106
107 return inters;
108 }
109
110
111
112
113 public Point2D getPoint(double t) {
114 if(Double.isInfinite(t))
115 throw new UnboundedShapeException(this);
116 t = Math.min(Math.max(t, t0), t1);
117 return branch.getPoint(t);
118 }
119
120 public double getPosition(java.awt.geom.Point2D point) {
121 if (!this.branch.contains(point))
122 return Double.NaN;
123 double t = this.branch.getPosition(point);
124 if (t-t0<-ACCURACY)
125 return Double.NaN;
126 if (t1-t<ACCURACY)
127 return Double.NaN;
128 return t;
129 }
130
131 public double project(java.awt.geom.Point2D point) {
132 double t = this.branch.project(point);
133 return Math.min(Math.max(t, t0), t1);
134 }
135
136 public HyperbolaBranchArc2D getReverseCurve() {
137 Hyperbola2D hyper = branch.hyperbola;
138 Hyperbola2D hyper2 = new Hyperbola2D(hyper.xc, hyper.yc, hyper.a,
139 hyper.b, hyper.theta, !hyper.direct);
140 return new HyperbolaBranchArc2D(new HyperbolaBranch2D(hyper2,
141 branch.positive), -t1, -t0);
142 }
143
144
145
146
147
148
149 public HyperbolaBranchArc2D getSubCurve(double t0, double t1) {
150 if (t1<t0)
151 return null;
152 t0 = Math.max(this.t0, t0);
153 t1 = Math.min(this.t1, t1);
154 return new HyperbolaBranchArc2D(branch, t0, t1);
155 }
156
157 public double getT0() {
158 return t0;
159 }
160
161 public double getT1() {
162 return t1;
163 }
164
165
166
167
168 public Box2D getBoundingBox() {
169 if (!this.isBounded())
170 throw new UnboundedShapeException(this);
171 return this.getAsPolyline(100).getBoundingBox();
172 }
173
174
175
176
177
178
179
180 public CurveSet2D<? extends HyperbolaBranchArc2D> clip(Box2D box) {
181
182 CurveSet2D<SmoothCurve2D> set = Curve2DUtils.clipSmoothCurve(this, box);
183
184
185 CurveArray2D<HyperbolaBranchArc2D> result =
186 new CurveArray2D<HyperbolaBranchArc2D>(set.getCurveNumber());
187
188
189 for (Curve2D curve : set.getCurves()) {
190 if (curve instanceof HyperbolaBranchArc2D)
191 result.addCurve((HyperbolaBranchArc2D) curve);
192 }
193 return result;
194 }
195
196 public double getDistance(java.awt.geom.Point2D point) {
197 Point2D p = getPoint(project(new Point2D(point)));
198 return p.getDistance(point);
199 }
200
201 public double getDistance(double x, double y) {
202 Point2D p = getPoint(project(new Point2D(x, y)));
203 return p.getDistance(x, y);
204 }
205
206 public boolean isBounded() {
207 if (t0==Double.NEGATIVE_INFINITY)
208 return false;
209 if (t1==Double.POSITIVE_INFINITY)
210 return false;
211 return true;
212 }
213
214 public boolean isEmpty() {
215 return false;
216 }
217
218 public HyperbolaBranchArc2D transform(AffineTransform2D trans) {
219
220 HyperbolaBranch2D branch2 = branch.transform(trans);
221
222
223 double startPos = Double.isInfinite(t0) ? Double.NEGATIVE_INFINITY
224 : branch2.project(this.getFirstPoint().transform(trans));
225 double endPos = Double.isInfinite(t1) ? Double.POSITIVE_INFINITY
226 : branch2.project(this.getLastPoint().transform(trans));
227
228
229 if(startPos>endPos){
230 return new HyperbolaBranchArc2D(branch2.getReverseCurve(),
231 endPos, startPos);
232 } else {
233 return new HyperbolaBranchArc2D(branch2, startPos, endPos);
234 }
235 }
236
237 public boolean contains(java.awt.geom.Point2D p) {
238 return this.contains(p.getX(), p.getY());
239 }
240
241 public boolean contains(double x, double y) {
242 if (!branch.contains(x, y))
243 return false;
244 double t = branch.getPosition(new Point2D(x, y));
245 if (t<t0)
246 return false;
247 if (t>t1)
248 return false;
249 return true;
250 }
251
252 public java.awt.geom.GeneralPath getGeneralPath() {
253 if (!this.isBounded())
254 throw new UnboundedShapeException(this);
255 return this.getAsPolyline(100).getGeneralPath();
256 }
257
258
259
260
261
262 @Override
263 public boolean equals(Object obj) {
264 if (!(obj instanceof HyperbolaBranchArc2D))
265 return false;
266 HyperbolaBranchArc2D arc = (HyperbolaBranchArc2D) obj;
267
268 if(!branch.equals(arc.branch)) return false;
269 if(Math.abs(t0-arc.t0)>Shape2D.ACCURACY) return false;
270 if(Math.abs(t1-arc.t1)>Shape2D.ACCURACY) return false;
271 return true;
272 }
273
274 @Override
275 public HyperbolaBranchArc2D clone() {
276 return new HyperbolaBranchArc2D(branch.clone(), t0, t1);
277 }
278 }