svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / rendering / symbols / styles / Line2DOffset.java @ 28218
History | View | Annotate | Download (16.4 KB)
1 | 21200 | vcaballero | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | *
|
||
19 | * For more information, contact:
|
||
20 | *
|
||
21 | * Generalitat Valenciana
|
||
22 | * Conselleria d'Infraestructures i Transport
|
||
23 | * Av. Blasco Ib??ez, 50
|
||
24 | * 46010 VALENCIA
|
||
25 | * SPAIN
|
||
26 | *
|
||
27 | * +34 963862235
|
||
28 | * gvsig@gva.es
|
||
29 | * www.gvsig.gva.es
|
||
30 | *
|
||
31 | * or
|
||
32 | *
|
||
33 | * IVER T.I. S.A
|
||
34 | * Salamanca 50
|
||
35 | * 46005 Valencia
|
||
36 | * Spain
|
||
37 | *
|
||
38 | * +34 963163400
|
||
39 | * dac@iver.es
|
||
40 | */
|
||
41 | package org.gvsig.fmap.mapcontext.rendering.symbols.styles; |
||
42 | |||
43 | import java.awt.Shape; |
||
44 | import java.awt.geom.Line2D; |
||
45 | import java.awt.geom.PathIterator; |
||
46 | import java.awt.geom.Point2D; |
||
47 | import java.util.ArrayList; |
||
48 | import java.util.Hashtable; |
||
49 | |||
50 | import org.gvsig.fmap.geom.primitive.GeneralPathX; |
||
51 | 25543 | vcaballero | import org.slf4j.Logger; |
52 | import org.slf4j.LoggerFactory; |
||
53 | 21200 | vcaballero | |
54 | import com.vividsolutions.jts.geom.Coordinate; |
||
55 | import com.vividsolutions.jts.geom.LineSegment; |
||
56 | /**
|
||
57 | *
|
||
58 | * Line2DOffset.java
|
||
59 | *
|
||
60 | *
|
||
61 | * @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008
|
||
62 | *
|
||
63 | */
|
||
64 | |||
65 | public class Line2DOffset { |
||
66 | 25543 | vcaballero | final static private Logger logger = LoggerFactory.getLogger(Line2DOffset.class); |
67 | 21200 | vcaballero | |
68 | public static GeneralPathX offsetLine(Shape p, double offset) { |
||
69 | |||
70 | 28218 | fdiaz | if (Math.abs(offset) < 1) { |
71 | 21200 | vcaballero | return new GeneralPathX(p); |
72 | } |
||
73 | PathIterator pi = p.getPathIterator(null); |
||
74 | double[] dataCoords = new double[6]; |
||
75 | Coordinate from = null, first = null; |
||
76 | 22506 | vcaballero | ArrayList segments = new ArrayList(); //<LineSegment> |
77 | 21200 | vcaballero | GeneralPathX offsetSegments = new GeneralPathX();
|
78 | 28218 | fdiaz | LineSegment line; |
79 | 21200 | vcaballero | try {
|
80 | while (!pi.isDone()) {
|
||
81 | // while not done
|
||
82 | int type = pi.currentSegment(dataCoords);
|
||
83 | |||
84 | switch (type) {
|
||
85 | case PathIterator.SEG_MOVETO: |
||
86 | from = new Coordinate(dataCoords[0], dataCoords[1]); |
||
87 | first = from; |
||
88 | break;
|
||
89 | |||
90 | case PathIterator.SEG_LINETO: |
||
91 | |||
92 | // System.out.println("SEG_LINETO");
|
||
93 | Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]); |
||
94 | 28218 | fdiaz | if(from.compareTo(to)!=0){ |
95 | line = new LineSegment(from, to);
|
||
96 | segments.add(line); |
||
97 | from = to; |
||
98 | } |
||
99 | 21200 | vcaballero | break;
|
100 | case PathIterator.SEG_CLOSE: |
||
101 | line = new LineSegment(from, first);
|
||
102 | segments.add(line); |
||
103 | from = first; |
||
104 | try {
|
||
105 | offsetSegments.append(offsetAndConsumeClosedSegments( |
||
106 | offset, segments), false);
|
||
107 | } catch (NotEnoughSegmentsToClosePathException e) {
|
||
108 | 25543 | vcaballero | logger.error( |
109 | 21200 | vcaballero | e.getMessage(), e); |
110 | } |
||
111 | break;
|
||
112 | |||
113 | } // end switch
|
||
114 | |||
115 | pi.next(); |
||
116 | } |
||
117 | offsetSegments.append(offsetAndConsumeSegments(offset, segments), |
||
118 | true);
|
||
119 | |||
120 | return offsetSegments;
|
||
121 | } catch (ParallelLinesCannotBeResolvedException e) {
|
||
122 | 25543 | vcaballero | logger.error(e.getMessage(), e); |
123 | 21200 | vcaballero | return new GeneralPathX(p); |
124 | } |
||
125 | } |
||
126 | |||
127 | private static GeneralPathX offsetAndConsumeSegments(double offset, |
||
128 | 22506 | vcaballero | ArrayList segments)
|
129 | 21200 | vcaballero | throws ParallelLinesCannotBeResolvedException {
|
130 | 22506 | vcaballero | Hashtable offsetLines = new Hashtable(); //<LineSegment, LineEquation> |
131 | 21200 | vcaballero | int segmentCount = segments.size();
|
132 | // first calculate offset lines with the starting point
|
||
133 | for (int i = 0; i < segmentCount; i++) { |
||
134 | 22506 | vcaballero | LineSegment segment = (LineSegment)segments.get(i); |
135 | 21200 | vcaballero | double theta = segment.angle();
|
136 | 28218 | fdiaz | //FIXME: ?Esto para qu? es?
|
137 | // if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){
|
||
138 | // theta=theta+0.00000000000001;
|
||
139 | // }
|
||
140 | 21200 | vcaballero | |
141 | double xOffset = offset * Math.sin(theta); |
||
142 | double yOffset = offset * Math.cos(theta); |
||
143 | |||
144 | Coordinate p0 = segment.p0; |
||
145 | double x0 = p0.x + xOffset;
|
||
146 | double y0 = p0.y - yOffset;
|
||
147 | |||
148 | Coordinate p1 = segment.p1; |
||
149 | double x1 = p1.x + xOffset;
|
||
150 | double y1 = p1.y - yOffset;
|
||
151 | |||
152 | LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1);
|
||
153 | offsetLines.put(segment, offsetLine); |
||
154 | } |
||
155 | |||
156 | /*
|
||
157 | * let's now calculate the end point of each segment with the point
|
||
158 | * where each line crosses the next one. this point will be the end
|
||
159 | * point of the first line, and the start point of its next one.
|
||
160 | */
|
||
161 | Point2D pIni = null; |
||
162 | Point2D pEnd = null; |
||
163 | GeneralPathX gpx = new GeneralPathX();
|
||
164 | for (int i = 0; i < segmentCount; i++) { |
||
165 | 22506 | vcaballero | LineSegment segment = (LineSegment)segments.get(0);
|
166 | LineEquation eq = (LineEquation)offsetLines.get(segment); |
||
167 | 21200 | vcaballero | if (i == 0) { |
168 | pIni = new Point2D.Double(eq.x, eq.y); |
||
169 | } else {
|
||
170 | pIni = pEnd; |
||
171 | } |
||
172 | |||
173 | if (i < segmentCount - 1) { |
||
174 | 28218 | fdiaz | LineEquation eq1 = (LineEquation) offsetLines.get(segments.get(1));
|
175 | try{
|
||
176 | pEnd = eq.resolve(eq1); |
||
177 | } catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma. |
||
178 | pEnd = new Point2D.Double(eq.xEnd, eq.yEnd); |
||
179 | gpx.append(new Line2D.Double(pIni, pEnd), true); // a?adimos una linea hasta el final del primer segmento |
||
180 | // y asignamos como punto final el principio del siguiente segmento
|
||
181 | // para que en la siguiente iteraci?n lo tome como punto inicial.
|
||
182 | pIni = pEnd; |
||
183 | pEnd = new Point2D.Double(eq1.x, eq1.y); |
||
184 | segments.remove(0);
|
||
185 | continue;
|
||
186 | } |
||
187 | 21200 | vcaballero | } else {
|
188 | pEnd = new Point2D.Double(eq.xEnd, eq.yEnd); |
||
189 | } |
||
190 | |||
191 | gpx.append(new Line2D.Double(pIni, pEnd), true); |
||
192 | segments.remove(0);
|
||
193 | } |
||
194 | return gpx;
|
||
195 | } |
||
196 | |||
197 | private static GeneralPathX offsetAndConsumeClosedSegments(double offset, |
||
198 | 22506 | vcaballero | ArrayList segments)
|
199 | 21200 | vcaballero | throws ParallelLinesCannotBeResolvedException,
|
200 | NotEnoughSegmentsToClosePathException { |
||
201 | int segmentCount = segments.size();
|
||
202 | if (segmentCount > 1) { |
||
203 | GeneralPathX openPath = offsetAndConsumeSegments(offset, segments); |
||
204 | openPath.closePath(); |
||
205 | return openPath;
|
||
206 | } |
||
207 | throw new NotEnoughSegmentsToClosePathException(segments); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | class LineEquation { |
||
212 | 28218 | fdiaz | double theta, m, x, y;
|
213 | 21200 | vcaballero | |
214 | double xEnd, yEnd; // just for simplicity of code |
||
215 | |||
216 | public LineEquation(double theta, double x, double y, double xEnd, |
||
217 | double yEnd) {
|
||
218 | 28218 | fdiaz | // this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente
|
219 | this.theta = theta;
|
||
220 | this.m = Math.tan(theta); |
||
221 | 21200 | vcaballero | this.x = x;
|
222 | this.y = y;
|
||
223 | this.xEnd = xEnd;
|
||
224 | this.yEnd = yEnd;
|
||
225 | } |
||
226 | |||
227 | public Point2D resolve(LineEquation otherLine) |
||
228 | throws ParallelLinesCannotBeResolvedException {
|
||
229 | /*
|
||
230 | 28218 | fdiaz | * line1 (this): y - y0 = m*(x - x0)
|
231 | * line2 (otherLine): y' - y'0 = m'*(x' - x'0)
|
||
232 | 21200 | vcaballero | */
|
233 | 28218 | fdiaz | |
234 | double X;
|
||
235 | double Y;
|
||
236 | if(Math.abs(this.x - this.xEnd)<0.00001) { //Esta linea es vertical |
||
237 | // System.out.println("1 VERTICAL");
|
||
238 | X = this.xEnd;
|
||
239 | if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
||
240 | // System.out.println(" 2 PERPENDICULAR");
|
||
241 | if(Math.abs(this.x - otherLine.x)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea. |
||
242 | // System.out.println(" MISMA LINEA");
|
||
243 | Y = otherLine.y; |
||
244 | } else { //No son la misma linea, entonces son paralelas, excepcion. |
||
245 | // System.out.println(" CASCO POR 1");
|
||
246 | throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
||
247 | } |
||
248 | } else if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
||
249 | // System.out.println(" 2 HORIZONTAL");
|
||
250 | Y = otherLine.y; |
||
251 | } else { //Si no |
||
252 | // System.out.println(" 2 CUALQUIERA");
|
||
253 | Y = otherLine.m*(X - otherLine.x)+otherLine.y; |
||
254 | 21200 | vcaballero | } |
255 | 28218 | fdiaz | |
256 | } else if (Math.abs(this.y - this.yEnd)<0.00001) { //Esta linea es horizontal |
||
257 | // System.out.println("1 HORIZONTAL");
|
||
258 | Y = this.yEnd;
|
||
259 | if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
||
260 | // System.out.println(" 2 HORIZONTAL");
|
||
261 | if(Math.abs(this.y - otherLine.y)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea. |
||
262 | // System.out.println(" MISMA LINEA");
|
||
263 | X = otherLine.x; |
||
264 | } else { //No son la misma linea, entonces son paralelas, excepcion. |
||
265 | // System.out.println(" CASCO POR 2");
|
||
266 | throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
||
267 | } |
||
268 | } else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
||
269 | // System.out.println(" 2 VERTICAL");
|
||
270 | X = otherLine.x; |
||
271 | } else { //Si no |
||
272 | // System.out.println(" 2 CUALQUIERA");
|
||
273 | X = (Y - otherLine.y)/otherLine.m +otherLine.x; |
||
274 | } |
||
275 | } else { //Esta linea no es ni vertical ni horizontal |
||
276 | // System.out.println("1 CUALQUIERA");
|
||
277 | if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
||
278 | // System.out.println(" 2 HORIZONTAL");
|
||
279 | Y = otherLine.y; |
||
280 | X = (Y - this.y)/this.m +this.x; |
||
281 | } else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
||
282 | // System.out.println(" 2 VERTICAL");
|
||
283 | X = otherLine.x; |
||
284 | Y = this.m*(X - this.x)+this.y; |
||
285 | } else if ((Math.abs(otherLine.m - this.m)<0.00001)) { //Tienen la misma pendiente |
||
286 | // System.out.println(" MISMA PENDIENTE");
|
||
287 | Y = otherLine.m*(this.x - otherLine.x)+otherLine.y;
|
||
288 | if (Math.abs(this.y - Y)<0.00001){ //Las lineas son la misma |
||
289 | // System.out.println(" MISMA LINEA");
|
||
290 | X = otherLine.x; |
||
291 | Y = otherLine.y; |
||
292 | } else {
|
||
293 | // System.out.println(" CASCO POR 3");
|
||
294 | throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
||
295 | } |
||
296 | } else {
|
||
297 | // System.out.println(" AMBAS CUALESQUIERA");
|
||
298 | double mTimesX = this.m * this.x; |
||
299 | X = (mTimesX - this.y - otherLine.m * otherLine.x + otherLine.y) / (this.m - otherLine.m); |
||
300 | Y = this.m * X - mTimesX + this.y; |
||
301 | } |
||
302 | 21200 | vcaballero | } |
303 | |||
304 | 28218 | fdiaz | // System.out.println("DEVOLVEMOS X = "+X+" Y = "+Y);
|
305 | return new Point2D.Double(X, Y); |
||
306 | 21200 | vcaballero | |
307 | } |
||
308 | |||
309 | public String toString() { |
||
310 | 28218 | fdiaz | return "Y - " + y + " = " + m + "*(X - " + x + ")"; |
311 | 21200 | vcaballero | } |
312 | } |
||
313 | |||
314 | class NotEnoughSegmentsToClosePathException extends Exception { |
||
315 | private static final long serialVersionUID = 95503944546535L; |
||
316 | |||
317 | 22506 | vcaballero | public NotEnoughSegmentsToClosePathException(ArrayList segments) { |
318 | 21200 | vcaballero | super("Need at least 2 segments to close a path. I've got " |
319 | + segments.size() + ".");
|
||
320 | } |
||
321 | } |
||
322 | |||
323 | class ParallelLinesCannotBeResolvedException extends Exception { |
||
324 | private static final long serialVersionUID = 8322556508820067641L; |
||
325 | |||
326 | public ParallelLinesCannotBeResolvedException(LineEquation eq1,
|
||
327 | LineEquation eq2) { |
||
328 | super("Lines '" + eq1 + "' and '" + eq2 |
||
329 | + "' are parallel and don't share any point!");
|
||
330 | } |
||
331 | } |
||
332 | //public class Line2DOffset {
|
||
333 | |||
334 | //private static final double TOL = 1E-8;
|
||
335 | //private static final double ANGLE_TOL = 0.01/180*Math.PI;
|
||
336 | |||
337 | //public static GeneralPathX offsetLine(Shape p, double offset) {
|
||
338 | |||
339 | //PathIterator pi = p.getPathIterator(null);
|
||
340 | //double[] dataCoords = new double[6];
|
||
341 | //Coordinate from = null, first = null;
|
||
342 | //ArrayList<LineSegment> segments = new ArrayList<LineSegment>();
|
||
343 | //GeneralPathX offsetSegments = new GeneralPathX();
|
||
344 | //try {
|
||
345 | //while (!pi.isDone()) {
|
||
346 | //// while not done
|
||
347 | //int type = pi.currentSegment(dataCoords);
|
||
348 | |||
349 | //switch (type) {
|
||
350 | //case PathIterator.SEG_MOVETO:
|
||
351 | //from = new Coordinate(dataCoords[0], dataCoords[1]);
|
||
352 | //first = from;
|
||
353 | //break;
|
||
354 | |||
355 | //case PathIterator.SEG_LINETO:
|
||
356 | |||
357 | //// System.out.println("SEG_LINETO");
|
||
358 | //Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]);
|
||
359 | //LineSegment line = new LineSegment(from, to);
|
||
360 | //int size = segments.size();
|
||
361 | //if (size>0) {
|
||
362 | //LineSegment prev = segments.get(size-1);
|
||
363 | //if (line.angle() == prev.angle()) {
|
||
364 | //if (Math.abs(line.p0.x - prev.p1.x) < TOL &&
|
||
365 | //Math.abs(line.p0.y - prev.p1.y) < TOL) {
|
||
366 | //prev.p1 = line.p1;
|
||
367 | //break;
|
||
368 | //}
|
||
369 | //}
|
||
370 | //}
|
||
371 | //from = to;
|
||
372 | //segments.add(line);
|
||
373 | |||
374 | //break;
|
||
375 | //case PathIterator.SEG_CLOSE:
|
||
376 | //line = new LineSegment(from, first);
|
||
377 | //segments.add(line);
|
||
378 | //from = first;
|
||
379 | //try {
|
||
380 | //offsetSegments.append(offsetAndConsumeClosedSegments(offset, segments), false);
|
||
381 | //} catch (NotEnoughSegmentsToClosePathException e) {
|
||
382 | //Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
|
||
383 | //}
|
||
384 | //break;
|
||
385 | |||
386 | //} // end switch
|
||
387 | |||
388 | //pi.next();
|
||
389 | //}
|
||
390 | //offsetSegments.append(offsetAndConsumeSegments(offset, segments), true);
|
||
391 | |||
392 | //return offsetSegments;
|
||
393 | //} catch (ParallelLinesCannotBeResolvedException e) {
|
||
394 | //Logger.getLogger(Line2DOffset.class).error(e.getMessage(), e);
|
||
395 | //return new GeneralPathX(p);
|
||
396 | //}
|
||
397 | //}
|
||
398 | |||
399 | //private static GeneralPathX offsetAndConsumeSegments(double offset, ArrayList<LineSegment> segments) {
|
||
400 | //Hashtable<LineSegment, LineEquation> offsetLines = new Hashtable<LineSegment, LineEquation>();
|
||
401 | //int segmentCount = segments.size();
|
||
402 | //// first calculate offset lines with the starting point
|
||
403 | //for (int i = 0; i < segmentCount; i++) {
|
||
404 | //LineSegment segment = segments.get(i);
|
||
405 | //double theta = segment.angle();
|
||
406 | |||
407 | //double xOffset = offset*Math.sin(theta);
|
||
408 | //double yOffset = offset*Math.cos(theta);
|
||
409 | |||
410 | //Coordinate p0 = segment.p0;
|
||
411 | //double x0 = p0.x + xOffset;
|
||
412 | //double y0 = p0.y - yOffset;
|
||
413 | |||
414 | //Coordinate p1 = segment.p1;
|
||
415 | //double x1 = p1.x + xOffset;
|
||
416 | //double y1 = p1.y - yOffset;
|
||
417 | |||
418 | //LineEquation offsetLine = new LineEquation(theta, x0, y0, x1, y1, offset);
|
||
419 | //offsetLines.put(segment, offsetLine);
|
||
420 | //}
|
||
421 | |||
422 | ///*
|
||
423 | //* let's now calculate the end point of each segment with
|
||
424 | //* the point where each line crosses the next one.
|
||
425 | //* this point will be the end point of the first line, and
|
||
426 | //* the start point of its next one.
|
||
427 | //*/
|
||
428 | //Point2D pIni = null;
|
||
429 | //Point2D pEnd = null;
|
||
430 | //GeneralPathX gpx = new GeneralPathX();
|
||
431 | //for (int i = 0; i < segmentCount; i++) {
|
||
432 | //LineSegment segment = segments.get(0);
|
||
433 | //LineEquation eq = offsetLines.get(segment);
|
||
434 | //Point2D pAux = null;
|
||
435 | //if (i < segmentCount -1) {
|
||
436 | //try {
|
||
437 | //pAux = eq.resolve(offsetLines.get(segments.get(1)));
|
||
438 | //if (i == 0) {
|
||
439 | //pIni = new Point2D.Double(eq.x, eq.y);
|
||
440 | //} else {
|
||
441 | //pIni = pEnd;
|
||
442 | //}
|
||
443 | //} catch (ParallelLinesCannotBeResolvedException e) {
|
||
444 | //segments.remove(0);
|
||
445 | //continue;
|
||
446 | //}
|
||
447 | //}
|
||
448 | |||
449 | |||
450 | //if (pAux != null) {
|
||
451 | //pEnd = pAux;
|
||
452 | //} else {
|
||
453 | //pEnd = new Point2D.Double(eq.xEnd, eq.yEnd);
|
||
454 | //}
|
||
455 | |||
456 | //gpx.append(new Line2D.Double(pIni, pEnd), true);
|
||
457 | //segments.remove(0);
|
||
458 | //}
|
||
459 | //return gpx;
|
||
460 | //}
|
||
461 | |||
462 | //private static GeneralPathX offsetAndConsumeClosedSegments(double offset, ArrayList<LineSegment> segments) throws ParallelLinesCannotBeResolvedException, NotEnoughSegmentsToClosePathException {
|
||
463 | //int segmentCount = segments.size();
|
||
464 | //if (segmentCount > 1) {
|
||
465 | //GeneralPathX openPath = offsetAndConsumeSegments(offset, segments);
|
||
466 | //openPath.closePath();
|
||
467 | //return openPath;
|
||
468 | //}
|
||
469 | //throw new NotEnoughSegmentsToClosePathException(segments);
|
||
470 | //}
|
||
471 | //}
|
||
472 | |||
473 | //class LineEquation {
|
||
474 | //double theta, x, y;
|
||
475 | //double xEnd, yEnd; // just for simplicity of code
|
||
476 | //double offset;
|
||
477 | |||
478 | //public LineEquation(double theta, double x, double y, double xEnd, double yEnd, double offset) {
|
||
479 | //this.theta = theta;
|
||
480 | //this.x = x;
|
||
481 | //this.y = y;
|
||
482 | //this.xEnd = xEnd;
|
||
483 | //this.yEnd = yEnd;
|
||
484 | //this.offset = offset;
|
||
485 | //}
|
||
486 | |||
487 | //public Point2D resolve(LineEquation otherLine) throws ParallelLinesCannotBeResolvedException {
|
||
488 | //double X;
|
||
489 | //double Y;
|
||
490 | |||
491 | |||
492 | ///*
|
||
493 | //* line1 (this): y - y0 = m*(x - x0)
|
||
494 | //* line2 (otherLine): y' - y'0 = m'*(x' - x'0)
|
||
495 | //*/
|
||
496 | //if (otherLine.theta == this.theta)
|
||
497 | //throw new ParallelLinesCannotBeResolvedException(this, otherLine);
|
||
498 | |||
499 | //if (Math.cos(theta) == 0) {
|
||
500 | |||
501 | //X = otherLine.x + offset*Math.cos(otherLine.theta);
|
||
502 | //Y = otherLine.y + offset*Math.sin(otherLine.theta);
|
||
503 | //} else if (Math.cos(otherLine.theta) == 0) {
|
||
504 | //X = x + offset*Math.cos(theta);
|
||
505 | //Y = y + offset*Math.sin(theta);
|
||
506 | //} else {
|
||
507 | ///*
|
||
508 | //* m*(X - x0) + y0 = m'*(X - x'0) + y0'
|
||
509 | //* X = (m*x0 - y0 - m'*x0' + y'0) / (m - m')
|
||
510 | //*/
|
||
511 | //double tanTheta = Math.tan(theta);
|
||
512 | //double otherTanTheta = Math.tan(otherLine.theta);
|
||
513 | //double thetaTimesX = tanTheta*this.x;
|
||
514 | //X = (thetaTimesX - this.y - otherTanTheta*otherLine.x + otherLine.y) / (tanTheta - otherTanTheta);
|
||
515 | |||
516 | ///*
|
||
517 | //* Y - y0 = m*(X - x0)
|
||
518 | //* Y = m*X - m*x0 + y0
|
||
519 | //*/
|
||
520 | //Y = tanTheta*X - thetaTimesX + this.y;
|
||
521 | //}
|
||
522 | //return new Point2D.Double(X, Y);
|
||
523 | //}
|
||
524 | |||
525 | //@Override
|
||
526 | //public String toString() {
|
||
527 | //return "Y - "+y+" = "+theta+"*(X - "+x+")";
|
||
528 | //}
|
||
529 | //}
|
||
530 | |||
531 | //class NotEnoughSegmentsToClosePathException extends Exception {
|
||
532 | //private static final long serialVersionUID = 95503944546535L;
|
||
533 | //public NotEnoughSegmentsToClosePathException(ArrayList<LineSegment> segments) {
|
||
534 | //super("Need at least 2 segments to close a path. I've got "+segments.size()+".");
|
||
535 | //}
|
||
536 | //}
|
||
537 | |||
538 | //class ParallelLinesCannotBeResolvedException extends Exception {
|
||
539 | //private static final long serialVersionUID = 8322556508820067641L;
|
||
540 | |||
541 | //public ParallelLinesCannotBeResolvedException(LineEquation eq1, LineEquation eq2) {
|
||
542 | //super("Lines '"+eq1+"' and '"+eq2+"' are parallel and don't share any point!");
|
||
543 | //}
|
||
544 | //} |