root / branches / pilotoDWG / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / cad / TrigonometricalFunctions.java @ 1631
History | View | Annotate | Download (17.6 KB)
1 | 1439 | fernando | /*
|
---|---|---|---|
2 | * Created on 10-feb-2005
|
||
3 | *
|
||
4 | * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
||
5 | *
|
||
6 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
7 | *
|
||
8 | * This program is free software; you can redistribute it and/or
|
||
9 | * modify it under the terms of the GNU General Public License
|
||
10 | * as published by the Free Software Foundation; either version 2
|
||
11 | * of the License, or (at your option) any later version.
|
||
12 | *
|
||
13 | * This program is distributed in the hope that it will be useful,
|
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
16 | * GNU General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU General Public License
|
||
19 | * along with this program; if not, write to the Free Software
|
||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
21 | *
|
||
22 | * For more information, contact:
|
||
23 | *
|
||
24 | * Generalitat Valenciana
|
||
25 | * Conselleria d'Infraestructures i Transport
|
||
26 | * Av. Blasco Ib??ez, 50
|
||
27 | * 46010 VALENCIA
|
||
28 | * SPAIN
|
||
29 | *
|
||
30 | * +34 963862235
|
||
31 | * gvsig@gva.es
|
||
32 | * www.gvsig.gva.es
|
||
33 | *
|
||
34 | * or
|
||
35 | *
|
||
36 | * IVER T.I. S.A
|
||
37 | * Salamanca 50
|
||
38 | * 46005 Valencia
|
||
39 | * Spain
|
||
40 | *
|
||
41 | * +34 963163400
|
||
42 | * dac@iver.es
|
||
43 | */
|
||
44 | package com.iver.cit.gvsig.fmap.edition.cad; |
||
45 | |||
46 | 1481 | vcaballero | import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
47 | |||
48 | import com.vividsolutions.jts.algorithm.LineIntersector; |
||
49 | 1451 | fernando | import com.vividsolutions.jts.algorithm.RobustCGAlgorithms; |
50 | import com.vividsolutions.jts.geom.Coordinate; |
||
51 | 1481 | vcaballero | import com.vividsolutions.jts.geom.GeometryFactory; |
52 | import com.vividsolutions.jts.geom.LineString; |
||
53 | import com.vividsolutions.jts.operation.linemerge.LineMerger; |
||
54 | 1451 | fernando | |
55 | 1439 | fernando | import java.awt.geom.Arc2D; |
56 | 1481 | vcaballero | import java.awt.geom.Line2D; |
57 | 1439 | fernando | import java.awt.geom.Point2D; |
58 | import java.awt.geom.Rectangle2D; |
||
59 | |||
60 | |||
61 | /**
|
||
62 | * Funciones de utilidad relacionadas con trigonometr?a
|
||
63 | */
|
||
64 | public class TrigonometricalFunctions { |
||
65 | /**
|
||
66 | 1467 | fernando | * Obtiene un par de puntos que definen la recta perpendicular a p1-p2 que
|
67 | * pasa por el punto perp
|
||
68 | 1447 | fernando | *
|
69 | 1451 | fernando | * @param p1 punto de la recta p1-p2
|
70 | * @param p2 punto de la recta p1-p2
|
||
71 | 1481 | vcaballero | * @param perp Punto por el que pasa la recta perpendicular, debe ser
|
72 | * distinto a p2
|
||
73 | 1447 | fernando | *
|
74 | 1451 | fernando | * @return Array con dos puntos que definen la recta resultante
|
75 | 1447 | fernando | */
|
76 | 1451 | fernando | public static Point2D[] getPerpendicular(Point2D p1, Point2D p2, |
77 | Point2D perp) {
|
||
78 | 1505 | fernando | if ((p2.getY() - p1.getY()) == 0) { |
79 | return new Point2D[] { |
||
80 | new Point2D.Double(perp.getX(), 0), |
||
81 | new Point2D.Double(perp.getX(), 1) |
||
82 | }; |
||
83 | } |
||
84 | |||
85 | 1451 | fernando | //Pendiente de la recta perpendicular
|
86 | double m = (p1.getX() - p2.getX()) / (p2.getY() - p1.getY());
|
||
87 | |||
88 | //b de la funcion de la recta perpendicular
|
||
89 | 1481 | vcaballero | double b = perp.getY() - (m * perp.getX());
|
90 | 1451 | fernando | |
91 | //Obtenemos un par de puntos
|
||
92 | Point2D[] res = new Point2D[2]; |
||
93 | 1481 | vcaballero | |
94 | 1451 | fernando | res[0] = new Point2D.Double(0, (m * 0) + b); |
95 | 1505 | fernando | res[1] = new Point2D.Double(1000, (m * 1000) + b); |
96 | 1451 | fernando | |
97 | return res;
|
||
98 | 1447 | fernando | } |
99 | |||
100 | /**
|
||
101 | 1439 | fernando | * Obtiene un arco a partir de 3 puntos. Devuelve null si no se puede crear
|
102 | 1604 | vcaballero | * el arco porque los puntos est?n alineados o los 3 puntos no son
|
103 | * distintos
|
||
104 | 1439 | fernando | *
|
105 | * @param p1
|
||
106 | * @param p2
|
||
107 | * @param p3
|
||
108 | *
|
||
109 | * @return Arco
|
||
110 | */
|
||
111 | public static Arc2D createArc(Point2D p1, Point2D p2, Point2D p3) { |
||
112 | 1505 | fernando | Point2D center = getCenter(p1, p2, p3);
|
113 | 1604 | vcaballero | |
114 | if (center == null) { |
||
115 | return null; |
||
116 | } |
||
117 | |||
118 | 1505 | fernando | double angle1 = getAngle(center, p1);
|
119 | double angle2 = getAngle(center, p3);
|
||
120 | double extent = angleDistance(angle1, angle2);
|
||
121 | |||
122 | 1451 | fernando | Coordinate[] coords = new Coordinate[4]; |
123 | coords[0] = new Coordinate(p1.getX(), p1.getY()); |
||
124 | coords[1] = new Coordinate(p2.getX(), p2.getY()); |
||
125 | coords[2] = new Coordinate(p3.getX(), p3.getY()); |
||
126 | coords[3] = new Coordinate(p1.getX(), p1.getY()); |
||
127 | |||
128 | if (!RobustCGAlgorithms.isCCW(coords)) {
|
||
129 | extent = (Math.PI * 2) - extent; |
||
130 | } else {
|
||
131 | 1447 | fernando | extent = -extent; |
132 | } |
||
133 | 1439 | fernando | |
134 | 1481 | vcaballero | //System.err.println("angle1:" + angle1);
|
135 | //System.err.println("angle2:" + getAngle(center, p2));
|
||
136 | //System.err.println("angle3:" + angle2);
|
||
137 | //System.err.println("extent:" + extent);
|
||
138 | 1439 | fernando | double Radio = p1.distance(center);
|
139 | double xR = center.getX() - Radio;
|
||
140 | double yR = center.getY() - Radio;
|
||
141 | double w = 2.0 * Radio; |
||
142 | double h = w;
|
||
143 | |||
144 | Rectangle2D.Double rBounds = new Rectangle2D.Double(xR, yR, w, h); |
||
145 | 1447 | fernando | Arc2D.Double resul = new Arc2D.Double(rBounds, |
146 | 1451 | fernando | Math.toDegrees((Math.PI * 2) - angle1), Math.toDegrees(extent), |
147 | Arc2D.OPEN);
|
||
148 | 1439 | fernando | |
149 | return resul;
|
||
150 | } |
||
151 | |||
152 | /**
|
||
153 | 1447 | fernando | * Obtiene el punto que se encuentra a una distancia 'dist' de la recta
|
154 | * p1-p2 y se encuentra en la recta perpendicular que pasa por perpPoint
|
||
155 | *
|
||
156 | * @param p1 Punto de la recta p1-p2
|
||
157 | * @param p2 Punto de la recta p1-p2
|
||
158 | * @param perpPoint Punto de la recta perpendicular
|
||
159 | * @param dist Distancia del punto que se quiere obtener a la recta p1-p2
|
||
160 | *
|
||
161 | * @return DOCUMENT ME!
|
||
162 | */
|
||
163 | public static Point2D getPerpendicularPoint(Point2D p1, Point2D p2, |
||
164 | Point2D perpPoint, double dist) { |
||
165 | 1604 | vcaballero | Point2D[] p = getPerpendicular(p1, p2, perpPoint); |
166 | Point2D unit = getUnitVector(p[0], p[1]); |
||
167 | |||
168 | return new Point2D.Double(perpPoint.getX() + (unit.getX() * dist), |
||
169 | perpPoint.getY() + (unit.getY() * dist)); |
||
170 | 1447 | fernando | } |
171 | |||
172 | /**
|
||
173 | 1604 | vcaballero | * Obtiene el centro del c?rculo que pasa por los tres puntos que se pasan
|
174 | * como par?metro
|
||
175 | 1505 | fernando | *
|
176 | * @param p1 primer punto del c?rculo cuyo centro se quiere obtener
|
||
177 | * @param p2 segundo punto del c?rculo cuyo centro se quiere obtener
|
||
178 | * @param p3 tercer punto del c?rculo cuyo centro se quiere obtener
|
||
179 | *
|
||
180 | 1604 | vcaballero | * @return Devuelve null si los puntos est?n alineados o no son 3 puntos
|
181 | * distintos
|
||
182 | 1505 | fernando | */
|
183 | public static Point2D getCenter(Point2D p1, Point2D p2, Point2D p3) { |
||
184 | if (p1.equals(p2) || p2.equals(p3) || p1.equals(p3)) {
|
||
185 | return null; |
||
186 | } |
||
187 | |||
188 | Point2D[] perp1 = getPerpendicular(p1, p2, |
||
189 | new Point2D.Double((p1.getX() + p2.getX()) / 2, |
||
190 | (p1.getY() + p2.getY()) / 2));
|
||
191 | Point2D[] perp2 = getPerpendicular(p2, p3, |
||
192 | new Point2D.Double((p2.getX() + p3.getX()) / 2, |
||
193 | (p2.getY() + p3.getY()) / 2));
|
||
194 | |||
195 | return getIntersection(perp1[0], perp1[1], perp2[0], perp2[1]); |
||
196 | } |
||
197 | |||
198 | /**
|
||
199 | 1439 | fernando | * Obtiene el centro del circulo que pasa por los puntos p1, p2 y p3
|
200 | *
|
||
201 | * @param p1
|
||
202 | * @param p2
|
||
203 | * @param p3
|
||
204 | *
|
||
205 | * @return Devuelve el punto o null si no hay ning?n c?rculo (puntos
|
||
206 | * alineados)
|
||
207 | */
|
||
208 | public static Point2D getCircleCenter(Point2D p1, Point2D p2, Point2D p3) { |
||
209 | double xC;
|
||
210 | double yC;
|
||
211 | double w;
|
||
212 | double h;
|
||
213 | |||
214 | // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
|
||
215 | // medios y obtenemos el centro. Luego calculamos el radio.
|
||
216 | // Puntos medios de los segmentos.
|
||
217 | double xm1;
|
||
218 | |||
219 | // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
|
||
220 | // medios y obtenemos el centro. Luego calculamos el radio.
|
||
221 | // Puntos medios de los segmentos.
|
||
222 | double ym1;
|
||
223 | |||
224 | // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
|
||
225 | // medios y obtenemos el centro. Luego calculamos el radio.
|
||
226 | // Puntos medios de los segmentos.
|
||
227 | double xm2;
|
||
228 | |||
229 | // Calculamos 2 secantes, tiramos perpendiculares por sus puntos
|
||
230 | // medios y obtenemos el centro. Luego calculamos el radio.
|
||
231 | // Puntos medios de los segmentos.
|
||
232 | double ym2;
|
||
233 | xm1 = (p1.getX() + p2.getX()) / 2.0;
|
||
234 | ym1 = (p1.getY() + p2.getY()) / 2.0;
|
||
235 | xm2 = (p2.getX() + p3.getX()) / 2.0;
|
||
236 | ym2 = (p2.getY() + p3.getY()) / 2.0;
|
||
237 | |||
238 | 1467 | fernando | /*
|
239 | * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
|
||
240 | * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
|
||
241 | */
|
||
242 | 1439 | fernando | |
243 | 1467 | fernando | // Pendientes de las perpendiculares y constantes
|
244 | 1439 | fernando | double mP1 = 0; |
245 | |||
246 | 1467 | fernando | /*
|
247 | * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
|
||
248 | * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
|
||
249 | */
|
||
250 | 1439 | fernando | |
251 | 1467 | fernando | // Pendientes de las perpendiculares y constantes
|
252 | 1439 | fernando | double mP2 = 0; |
253 | |||
254 | 1467 | fernando | /*
|
255 | * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
|
||
256 | * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
|
||
257 | */
|
||
258 | 1439 | fernando | |
259 | 1467 | fernando | // Pendientes de las perpendiculares y constantes
|
260 | 1439 | fernando | double A1;
|
261 | |||
262 | 1467 | fernando | /*
|
263 | * g.setColor(Color.GRAY); g.draw3DRect((int)xm1, (int) ym1, 1, 1,
|
||
264 | * true); g.draw3DRect((int)xm2, (int) ym2, 1, 1, true);
|
||
265 | */
|
||
266 | 1439 | fernando | |
267 | 1467 | fernando | // Pendientes de las perpendiculares y constantes
|
268 | 1439 | fernando | double A2;
|
269 | boolean bPerp1 = false; |
||
270 | boolean bPerp2 = false; |
||
271 | |||
272 | if ((p2.getY() - p1.getY()) == 0) { |
||
273 | A1 = ym1; |
||
274 | bPerp1 = true;
|
||
275 | } else {
|
||
276 | mP1 = (p2.getX() - p1.getX()) / (p1.getY() - p2.getY()); |
||
277 | A1 = ym1 - (xm1 * mP1); |
||
278 | } |
||
279 | |||
280 | if ((p2.getY() - p3.getY()) == 0) { |
||
281 | A2 = ym2; |
||
282 | bPerp2 = true;
|
||
283 | } else {
|
||
284 | mP2 = (p3.getX() - p2.getX()) / (p2.getY() - p3.getY()); |
||
285 | A2 = ym2 - (xm2 * mP2); |
||
286 | } |
||
287 | |||
288 | if (mP2 == mP1) {
|
||
289 | return null; // Error, 3 puntos alineados. No puede pasar un arco |
||
290 | } else {
|
||
291 | xC = (A2 - A1) / (mP1 - mP2); |
||
292 | |||
293 | if (!bPerp1) {
|
||
294 | yC = (xC * mP1) + A1; |
||
295 | } else {
|
||
296 | yC = (xC * mP2) + A2; |
||
297 | } |
||
298 | } |
||
299 | |||
300 | return new Point2D.Double(xC, yC); |
||
301 | } |
||
302 | |||
303 | /**
|
||
304 | * Obtiene un c?rculo a partir de 3 puntos. Devuelve null si no se puede
|
||
305 | * crear el c?ruclo porque los puntos est?n alineados
|
||
306 | *
|
||
307 | * @param p1
|
||
308 | * @param p2
|
||
309 | * @param p3
|
||
310 | *
|
||
311 | * @return C?rculo
|
||
312 | */
|
||
313 | 1467 | fernando | static public Arc2D createCircle(Point2D p1, Point2D p2, Point2D p3) //, |
314 | // Graphics
|
||
315 | // g)
|
||
316 | 1439 | fernando | { |
317 | Point2D center = getCircleCenter(p1, p2, p3);
|
||
318 | |||
319 | double Radio = p1.distance(center);
|
||
320 | double xR = center.getX() - Radio;
|
||
321 | double yR = center.getY() - Radio;
|
||
322 | double w = 2.0 * Radio; |
||
323 | double h = w;
|
||
324 | |||
325 | Rectangle2D.Double rBounds = new Rectangle2D.Double(xR, yR, w, h); |
||
326 | Arc2D.Double resul = new Arc2D.Double(rBounds, 0.0, 360.0, Arc2D.OPEN); |
||
327 | |||
328 | return resul;
|
||
329 | } |
||
330 | |||
331 | /**
|
||
332 | * Obtiene el ?ngulo del vector que se pasa como par?metro con el vector
|
||
333 | * horizontal de izquierda a derecha
|
||
334 | *
|
||
335 | * @param start punto origen del vector
|
||
336 | * @param end punto destino del vector
|
||
337 | *
|
||
338 | * @return angulo en radianes
|
||
339 | */
|
||
340 | public static double getAngle(Point2D start, Point2D end) { |
||
341 | double angle = Math.acos((end.getX() - start.getX()) / start.distance( |
||
342 | end)); |
||
343 | |||
344 | if (start.getY() > end.getY()) {
|
||
345 | angle = -angle; |
||
346 | } |
||
347 | |||
348 | if (angle < 0) { |
||
349 | angle += (2 * Math.PI); |
||
350 | } |
||
351 | |||
352 | return angle;
|
||
353 | } |
||
354 | |||
355 | /**
|
||
356 | 1480 | fernando | * Devuelve la distancia desde angle1 a angle2. Angulo en radianes de
|
357 | * diferencia entre angle1 y angle2 en sentido antihorario
|
||
358 | 1439 | fernando | *
|
359 | 1447 | fernando | * @param angle1 angulo en radianes. Debe ser positivo y no dar ninguna
|
360 | * vuelta a la circunferencia
|
||
361 | * @param angle2 angulo en radianes. Debe ser positivo y no dar ninguna
|
||
362 | * vuelta a la circunferencia
|
||
363 | 1439 | fernando | *
|
364 | * @return distancia entre los ?ngulos
|
||
365 | */
|
||
366 | public static double angleDistance(double angle1, double angle2) { |
||
367 | if (angle1 < angle2) {
|
||
368 | return angle2 - angle1;
|
||
369 | } else {
|
||
370 | 1447 | fernando | return ((Math.PI * 2) - angle1) + angle2; |
371 | 1439 | fernando | } |
372 | } |
||
373 | 1505 | fernando | |
374 | 1481 | vcaballero | /**
|
375 | 1505 | fernando | * Devuelve el punto de la recta que viene dada por los puntos p1 y p2 a
|
376 | * una distancia radio de p1.
|
||
377 | 1481 | vcaballero | *
|
378 | * @param p1 DOCUMENT ME!
|
||
379 | * @param p2 DOCUMENT ME!
|
||
380 | * @param radio DOCUMENT ME!
|
||
381 | *
|
||
382 | * @return DOCUMENT ME!
|
||
383 | */
|
||
384 | public static Point2D getPoint(Point2D p1, Point2D p2, double radio) { |
||
385 | Point2D paux = new Point2D.Double(p2.getX() - p1.getX(), |
||
386 | p2.getY() - p1.getY()); |
||
387 | double v = Math.sqrt(Math.pow((double) paux.getX(), (double) 2) + |
||
388 | Math.pow((double) paux.getY(), (double) 2)); |
||
389 | paux = new Point2D.Double(paux.getX() / v, paux.getY() / v); |
||
390 | 1467 | fernando | |
391 | 1481 | vcaballero | Point2D aux1 = new Point2D.Double(p1.getX() + (radio * paux.getX()), |
392 | p1.getY() + (radio * paux.getY())); |
||
393 | |||
394 | return aux1;
|
||
395 | } |
||
396 | 1631 | vcaballero | /**
|
397 | * Devuelve el punto a una distancia radio del punto p1 y aplicandole una ngulo an.
|
||
398 | * una distancia radio de p1.
|
||
399 | *
|
||
400 | * @param p1 DOCUMENT ME!
|
||
401 | * @param p2 DOCUMENT ME!
|
||
402 | * @param radio DOCUMENT ME!
|
||
403 | *
|
||
404 | * @return DOCUMENT ME!
|
||
405 | */
|
||
406 | public static Point2D getPoint(Point2D p1, double an, double radio) { |
||
407 | double x=(radio*Math.cos(an))+p1.getX(); |
||
408 | double y=(radio*Math.sin(an))+p1.getY(); |
||
409 | |||
410 | Point2D p=new Point2D.Double(x,y); |
||
411 | |||
412 | return p;
|
||
413 | } |
||
414 | 1505 | fernando | |
415 | /**
|
||
416 | 1480 | fernando | * Devuelve la menor distancia desde angle1 a angle2.
|
417 | *
|
||
418 | * @param angle1 angulo en radianes. Debe ser positivo y no dar ninguna
|
||
419 | * vuelta a la circunferencia
|
||
420 | * @param angle2 angulo en radianes. Debe ser positivo y no dar ninguna
|
||
421 | * vuelta a la circunferencia
|
||
422 | *
|
||
423 | * @return distancia entre los ?ngulos
|
||
424 | */
|
||
425 | public static double absoluteAngleDistance(double angle1, double angle2) { |
||
426 | double d = Math.abs(angle1 - angle2); |
||
427 | 1505 | fernando | |
428 | if (d < Math.PI) { |
||
429 | return d;
|
||
430 | } else {
|
||
431 | if (angle1 < angle2) {
|
||
432 | angle2 -= (Math.PI * 2); |
||
433 | } else {
|
||
434 | angle1 -= (Math.PI * 2); |
||
435 | 1480 | fernando | } |
436 | 1505 | fernando | |
437 | 1480 | fernando | return Math.abs(angle1 - angle2); |
438 | } |
||
439 | } |
||
440 | |||
441 | /**
|
||
442 | 1467 | fernando | * Devuelve el punto de la intersecci?n entre las lineas p1-p2 y p3-p4.
|
443 | *
|
||
444 | * @param p1 punto de la recta p1-p2
|
||
445 | * @param p2 punto de la recta p1-p2
|
||
446 | * @param p3 punto de la recta p3-p4
|
||
447 | * @param p4 punto de la recta p3-p4
|
||
448 | *
|
||
449 | * @return DOCUMENT ME!
|
||
450 | *
|
||
451 | * @throws RuntimeException DOCUMENT ME!
|
||
452 | */
|
||
453 | public static Point2D getIntersection(Point2D p1, Point2D p2, Point2D p3, |
||
454 | Point2D p4) {
|
||
455 | double m1 = Double.POSITIVE_INFINITY; |
||
456 | |||
457 | if ((p2.getX() - p1.getX()) != 0) { |
||
458 | m1 = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX()); |
||
459 | } |
||
460 | |||
461 | double m2 = Double.POSITIVE_INFINITY; |
||
462 | |||
463 | if ((p4.getX() - p3.getX()) != 0) { |
||
464 | m2 = (p4.getY() - p3.getY()) / (p4.getX() - p3.getX()); |
||
465 | } |
||
466 | |||
467 | if ((m1 == Double.POSITIVE_INFINITY) && |
||
468 | (m2 == Double.POSITIVE_INFINITY)) {
|
||
469 | return null; |
||
470 | } |
||
471 | |||
472 | double b1 = p2.getY() - (m1 * p2.getX());
|
||
473 | |||
474 | double b2 = p4.getY() - (m2 * p4.getX());
|
||
475 | |||
476 | if ((m1 != Double.POSITIVE_INFINITY) && |
||
477 | (m2 != Double.POSITIVE_INFINITY)) {
|
||
478 | if (m1 == m2) {
|
||
479 | return null; |
||
480 | } |
||
481 | |||
482 | double x = (b2 - b1) / (m1 - m2);
|
||
483 | |||
484 | return new Point2D.Double(x, (m1 * x) + b1); |
||
485 | } else if (m1 == Double.POSITIVE_INFINITY) { |
||
486 | double x = p1.getX();
|
||
487 | |||
488 | return new Point2D.Double(x, (m2 * x) + b2); |
||
489 | } else if (m2 == Double.POSITIVE_INFINITY) { |
||
490 | double x = p3.getX();
|
||
491 | |||
492 | return new Point2D.Double(x, (m1 * x) + b1); |
||
493 | } |
||
494 | |||
495 | //no llega nunca
|
||
496 | throw new RuntimeException("BUG!"); |
||
497 | } |
||
498 | |||
499 | /**
|
||
500 | 1481 | vcaballero | * Devuelve un vector unitario en forma de punto a partir de dos puntos.
|
501 | *
|
||
502 | * @param p1 punto origen.
|
||
503 | * @param p2 punto destino.
|
||
504 | *
|
||
505 | * @return vector unitario.
|
||
506 | */
|
||
507 | public static Point2D getUnitVector(Point2D p1, Point2D p2) { |
||
508 | Point2D paux = new Point2D.Double(p2.getX() - p1.getX(), |
||
509 | p2.getY() - p1.getY()); |
||
510 | double v = Math.sqrt(Math.pow((double) paux.getX(), (double) 2) + |
||
511 | Math.pow((double) paux.getY(), (double) 2)); |
||
512 | paux = new Point2D.Double(paux.getX() / v, paux.getY() / v); |
||
513 | |||
514 | return paux;
|
||
515 | } |
||
516 | 1505 | fernando | |
517 | /**
|
||
518 | 1604 | vcaballero | * Devuelve true si los puntos que se pasan como par?metros est?n situados
|
519 | * en el mismo orden que las agujas del reloj o si por el contrario no lo
|
||
520 | * estan.
|
||
521 | *
|
||
522 | * @param p1 primer punto
|
||
523 | * @param p2 segundo punto
|
||
524 | * @param p3 tercer punto
|
||
525 | *
|
||
526 | * @return True si estan en el sentido de la agujas del reloj.
|
||
527 | */
|
||
528 | public static boolean isCCW(Point2D p1, Point2D p2, Point2D p3) { |
||
529 | Coordinate[] coords = new Coordinate[4]; |
||
530 | coords[0] = new Coordinate(p1.getX(), p1.getY()); |
||
531 | coords[1] = new Coordinate(p2.getX(), p2.getY()); |
||
532 | coords[2] = new Coordinate(p3.getX(), p3.getY()); |
||
533 | coords[3] = new Coordinate(p1.getX(), p1.getY()); |
||
534 | |||
535 | return RobustCGAlgorithms.isCCW(coords);
|
||
536 | } |
||
537 | |||
538 | /**
|
||
539 | 1505 | fernando | * DOCUMENT ME!
|
540 | *
|
||
541 | * @param antp DOCUMENT ME!
|
||
542 | * @param lastp DOCUMENT ME!
|
||
543 | * @param interp DOCUMENT ME!
|
||
544 | * @param point DOCUMENT ME!
|
||
545 | *
|
||
546 | * @return DOCUMENT ME!
|
||
547 | */
|
||
548 | public static boolean isLowAngle(Point2D antp, Point2D lastp, |
||
549 | Point2D interp, Point2D point) { |
||
550 | 1481 | vcaballero | ///double ob=lastp.distance(point);
|
551 | ///Point2D[] aux=getPerpendicular(lastp,interp,point);
|
||
552 | ///Point2D intersect=getIntersection(aux[0],aux[1],lastp,interp);
|
||
553 | ///double pb=intersect.distance(point);
|
||
554 | ///double a=Math.asin(pb/ob);
|
||
555 | Coordinate[] coords = new Coordinate[4]; |
||
556 | coords[0] = new Coordinate(lastp.getX(), lastp.getY()); |
||
557 | coords[1] = new Coordinate(interp.getX(), interp.getY()); |
||
558 | coords[2] = new Coordinate(point.getX(), point.getY()); |
||
559 | coords[3] = new Coordinate(lastp.getX(), lastp.getY()); |
||
560 | 1505 | fernando | |
561 | try {
|
||
562 | double angle1 = getAngle(antp, lastp);
|
||
563 | System.out.println("angle1= " + angle1); |
||
564 | |||
565 | double angle2 = getAngle(lastp, point);
|
||
566 | System.out.println("angle2= " + angle2); |
||
567 | |||
568 | /*if (lastp.getX()<antp.getX()){
|
||
569 | System.out.println("angleDiff 2 1= "+angleDistance(angle2,angle1));
|
||
570 | System.out.println("angleDiff 1 2= "+angleDistance(angle1,angle2));
|
||
571 | if (angleDistance(angle2,angle1)>Math.PI){
|
||
572 | |||
573 | if (RobustCGAlgorithms.isCCW(coords)) {
|
||
574 | System.out.println("izquierda,arriba,true");
|
||
575 | return true;
|
||
576 | } else{
|
||
577 | System.out.println("izquierda,arriba,false");
|
||
578 | }
|
||
579 | }else {
|
||
580 | if (!RobustCGAlgorithms.isCCW(coords)) {
|
||
581 | System.out.println("izquierda,abajo,true");
|
||
582 | return true;
|
||
583 | } else{
|
||
584 | System.out.println("izquierda,abajo,false");
|
||
585 | }
|
||
586 | }
|
||
587 | }else if (lastp.getX()>antp.getX()){
|
||
588 | */
|
||
589 | System.out.println("angleDifl 2 1= " + |
||
590 | angleDistance(angle2, angle1)); |
||
591 | System.out.println("angleDifl 1 2= " + |
||
592 | angleDistance(angle1, angle2)); |
||
593 | |||
594 | if (angleDistance(angle2, angle1) > Math.PI) { |
||
595 | if (RobustCGAlgorithms.isCCW(coords)) {
|
||
596 | System.out.println("derecha,arriba,true"); |
||
597 | |||
598 | 1481 | vcaballero | return true; |
599 | 1505 | fernando | } else {
|
600 | System.out.println("derecha,arriba,false"); |
||
601 | 1481 | vcaballero | } |
602 | 1505 | fernando | } else {
|
603 | 1481 | vcaballero | if (!RobustCGAlgorithms.isCCW(coords)) {
|
604 | System.out.println("derecha,abajo,true"); |
||
605 | 1505 | fernando | |
606 | 1481 | vcaballero | return true; |
607 | 1505 | fernando | } else {
|
608 | 1481 | vcaballero | System.out.println("derecha,abajo,false"); |
609 | } |
||
610 | } |
||
611 | 1505 | fernando | |
612 | //}
|
||
613 | } catch (Exception e) { |
||
614 | 1481 | vcaballero | System.out.println("false"); |
615 | 1505 | fernando | |
616 | 1481 | vcaballero | return true; |
617 | } |
||
618 | 1505 | fernando | |
619 | 1481 | vcaballero | return false; |
620 | } |
||
621 | 1505 | fernando | |
622 | 1481 | vcaballero | /**
|
623 | 1467 | fernando | * DOCUMENT ME!
|
624 | *
|
||
625 | * @param args DOCUMENT ME!
|
||
626 | */
|
||
627 | public static void main(String[] args) { |
||
628 | System.out.println(getIntersection(new Point2D.Double(0, 0), |
||
629 | new Point2D.Double(2, 2), new Point2D.Double(3, 3), |
||
630 | new Point2D.Double(3, 4))); |
||
631 | System.out.println(getIntersection(new Point2D.Double(2, 3), |
||
632 | new Point2D.Double(2, 2), new Point2D.Double(3, 3), |
||
633 | new Point2D.Double(3, 4))); |
||
634 | System.out.println(getIntersection(new Point2D.Double(0, 0), |
||
635 | new Point2D.Double(2, 2), new Point2D.Double(1, 0), |
||
636 | new Point2D.Double(2, 3))); |
||
637 | System.out.println(getIntersection(new Point2D.Double(0, 4), |
||
638 | new Point2D.Double(2, 4), new Point2D.Double(3, 3), |
||
639 | new Point2D.Double(0, 0))); |
||
640 | } |
||
641 | 1439 | fernando | } |