Revision 28217
trunk/libraries/libFMap/src/com/iver/cit/gvsig/fmap/core/styles/Line2DOffset.java | ||
---|---|---|
53 | 53 |
import com.vividsolutions.jts.geom.Coordinate; |
54 | 54 |
import com.vividsolutions.jts.geom.LineSegment; |
55 | 55 |
/** |
56 |
*
|
|
56 |
* |
|
57 | 57 |
* Line2DOffset.java |
58 | 58 |
* |
59 |
*
|
|
59 |
* |
|
60 | 60 |
* @author jaume dominguez faus - jaume.dominguez@iver.es Jan 3, 2008 |
61 | 61 |
* |
62 | 62 |
*/ |
... | ... | |
65 | 65 |
|
66 | 66 |
public static GeneralPathX offsetLine(Shape p, double offset) { |
67 | 67 |
|
68 |
if (Math.abs(offset) <= 1) {
|
|
68 |
if (Math.abs(offset) < 1) { |
|
69 | 69 |
return new GeneralPathX(p); |
70 | 70 |
} |
71 | 71 |
PathIterator pi = p.getPathIterator(null); |
... | ... | |
73 | 73 |
Coordinate from = null, first = null; |
74 | 74 |
ArrayList<LineSegment> segments = new ArrayList<LineSegment>(); |
75 | 75 |
GeneralPathX offsetSegments = new GeneralPathX(); |
76 |
LineSegment line; |
|
76 | 77 |
try { |
77 | 78 |
while (!pi.isDone()) { |
78 | 79 |
// while not done |
... | ... | |
88 | 89 |
|
89 | 90 |
// System.out.println("SEG_LINETO"); |
90 | 91 |
Coordinate to = new Coordinate(dataCoords[0], dataCoords[1]); |
91 |
LineSegment line = new LineSegment(from, to); |
|
92 |
segments.add(line); |
|
93 |
from = to; |
|
92 |
if(from.compareTo(to)!=0){ |
|
93 |
line = new LineSegment(from, to); |
|
94 |
segments.add(line); |
|
95 |
from = to; |
|
96 |
} |
|
94 | 97 |
break; |
95 | 98 |
case PathIterator.SEG_CLOSE: |
96 | 99 |
line = new LineSegment(from, first); |
... | ... | |
128 | 131 |
for (int i = 0; i < segmentCount; i++) { |
129 | 132 |
LineSegment segment = segments.get(i); |
130 | 133 |
double theta = segment.angle(); |
131 |
if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){ |
|
132 |
theta=theta+0.00000000000001; |
|
133 |
} |
|
134 |
//FIXME: ?Esto para qu? es? |
|
135 |
// if (Math.abs(theta) % (Math.PI*0.5) < 0.00001){ |
|
136 |
// theta=theta+0.00000000000001; |
|
137 |
// } |
|
134 | 138 |
|
135 | 139 |
double xOffset = offset * Math.sin(theta); |
136 | 140 |
double yOffset = offset * Math.cos(theta); |
... | ... | |
165 | 169 |
} |
166 | 170 |
|
167 | 171 |
if (i < segmentCount - 1) { |
168 |
pEnd = eq.resolve(offsetLines.get(segments.get(1))); |
|
172 |
LineEquation eq1 = offsetLines.get(segments.get(1)); |
|
173 |
try{ |
|
174 |
pEnd = eq.resolve(eq1); |
|
175 |
} catch (ParallelLinesCannotBeResolvedException e) { //Las lineas son paralelas y NO son la misma. |
|
176 |
pEnd = new Point2D.Double(eq.xEnd, eq.yEnd); |
|
177 |
gpx.append(new Line2D.Double(pIni, pEnd), true); // a?adimos una linea hasta el final del primer segmento |
|
178 |
// y asignamos como punto final el principio del siguiente segmento |
|
179 |
// para que en la siguiente iteraci?n lo tome como punto inicial. |
|
180 |
pIni = pEnd; |
|
181 |
pEnd = new Point2D.Double(eq1.x, eq1.y); |
|
182 |
segments.remove(0); |
|
183 |
continue; |
|
184 |
} |
|
169 | 185 |
} else { |
170 | 186 |
pEnd = new Point2D.Double(eq.xEnd, eq.yEnd); |
171 | 187 |
} |
... | ... | |
191 | 207 |
} |
192 | 208 |
|
193 | 209 |
class LineEquation { |
194 |
double theta, x, y; |
|
210 |
double theta, m, x, y;
|
|
195 | 211 |
|
196 | 212 |
double xEnd, yEnd; // just for simplicity of code |
197 | 213 |
|
198 | 214 |
public LineEquation(double theta, double x, double y, double xEnd, |
199 | 215 |
double yEnd) { |
200 |
this.theta = Math.tan(theta); |
|
216 |
// this.theta = Math.tan(theta); //Esto es un error, no podemos confundir el angulo de la recta con su pendiente |
|
217 |
this.theta = theta; |
|
218 |
this.m = Math.tan(theta); |
|
201 | 219 |
this.x = x; |
202 | 220 |
this.y = y; |
203 | 221 |
this.xEnd = xEnd; |
... | ... | |
207 | 225 |
public Point2D resolve(LineEquation otherLine) |
208 | 226 |
throws ParallelLinesCannotBeResolvedException { |
209 | 227 |
/* |
210 |
* line1 (this): y - y0 = m*(x - x0) line2 (otherLine): y' - y'0 =
|
|
211 |
* m'*(x' - x'0) |
|
228 |
* line1 (this): y - y0 = m*(x - x0) |
|
229 |
* line2 (otherLine): y' - y'0 = m'*(x' - x'0)
|
|
212 | 230 |
*/ |
213 |
if (otherLine.theta == this.theta) { |
|
214 |
if (this.xEnd == otherLine.x && this.yEnd == otherLine.y) { |
|
215 |
return new Point2D.Double(otherLine.x, otherLine.y); |
|
231 |
|
|
232 |
double X; |
|
233 |
double Y; |
|
234 |
if(Math.abs(this.x - this.xEnd)<0.00001) { //Esta linea es vertical |
|
235 |
X = this.xEnd; |
|
236 |
if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
|
237 |
if(Math.abs(this.x - otherLine.x)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea. |
|
238 |
Y = otherLine.y; |
|
239 |
} else { //No son la misma linea, entonces son paralelas, excepcion. |
|
240 |
throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
|
241 |
} |
|
242 |
} else if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
|
243 |
Y = otherLine.y; |
|
244 |
} else { //Si la otra linea no es ni vertical ni horizontal |
|
245 |
Y = otherLine.m*(X - otherLine.x)+otherLine.y; |
|
216 | 246 |
} |
217 |
throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
|
247 |
|
|
248 |
} else if (Math.abs(this.y - this.yEnd)<0.00001) { //Esta linea es horizontal |
|
249 |
Y = this.yEnd; |
|
250 |
if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
|
251 |
if(Math.abs(this.y - otherLine.y)<0.00001){ //Son la misma linea, devolvemos el primer punto de la otra linea. |
|
252 |
X = otherLine.x; |
|
253 |
} else { //No son la misma linea, entonces son paralelas, excepcion. |
|
254 |
throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
|
255 |
} |
|
256 |
} else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
|
257 |
X = otherLine.x; |
|
258 |
} else { //Si la otra linea no es ni vertical ni horizontal |
|
259 |
X = (Y - otherLine.y)/otherLine.m +otherLine.x; |
|
260 |
} |
|
261 |
} else { //Esta linea no es ni vertical ni horizontal |
|
262 |
if (Math.abs(otherLine.y - otherLine.yEnd)<0.00001) { //La otra linea es horizontal |
|
263 |
Y = otherLine.y; |
|
264 |
X = (Y - this.y)/this.m +this.x; |
|
265 |
} else if (Math.abs(otherLine.x - otherLine.xEnd)<0.00001){//La otra linea es vertical |
|
266 |
X = otherLine.x; |
|
267 |
Y = this.m*(X - this.x)+this.y; |
|
268 |
} else if ((Math.abs(otherLine.m - this.m)<0.00001)) { //Tienen la misma pendiente |
|
269 |
Y = otherLine.m*(this.x - otherLine.x)+otherLine.y; |
|
270 |
if (Math.abs(this.y - Y)<0.00001){ //Las lineas son la misma |
|
271 |
X = otherLine.x; |
|
272 |
Y = otherLine.y; |
|
273 |
} else { |
|
274 |
throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
|
275 |
} |
|
276 |
} else { //Si la otra linea no es ni vertical ni horizontal |
|
277 |
double mTimesX = this.m * this.x; |
|
278 |
X = (mTimesX - this.y - otherLine.m * otherLine.x + otherLine.y) / (this.m - otherLine.m); |
|
279 |
Y = this.m * X - mTimesX + this.y; |
|
280 |
} |
|
218 | 281 |
} |
219 |
|
|
220 |
/* |
|
221 |
* m*(X - x0) + y0 = m'*(X - x'0) + y0' X = (m*x0 - y0 - m'*x0' + y'0) / |
|
222 |
* (m - m') |
|
223 |
*/ |
|
224 |
double thetaTimesX = this.theta * this.x; |
|
225 |
double X = (thetaTimesX - this.y - otherLine.theta * otherLine.x + otherLine.y) |
|
226 |
/ (this.theta - otherLine.theta); |
|
227 |
|
|
228 |
/* |
|
229 |
* Y - y0 = m*(X - x0) Y = m*X - m*x0 + y0 |
|
230 |
*/ |
|
231 |
double Y = this.theta * X - thetaTimesX + this.y; |
|
232 | 282 |
return new Point2D.Double(X, Y); |
233 | 283 |
} |
234 | 284 |
|
235 | 285 |
@Override |
236 | 286 |
public String toString() { |
237 |
return "Y - " + y + " = " + theta + "*(X - " + x + ")";
|
|
287 |
return "Y - " + y + " = " + m + "*(X - " + x + ")";
|
|
238 | 288 |
} |
239 | 289 |
} |
240 | 290 |
|
... | ... | |
420 | 470 |
//* line1 (this): y - y0 = m*(x - x0) |
421 | 471 |
//* line2 (otherLine): y' - y'0 = m'*(x' - x'0) |
422 | 472 |
//*/ |
423 |
//if (otherLine.theta == this.theta)
|
|
473 |
//if (otherLine.theta == this.theta) |
|
424 | 474 |
//throw new ParallelLinesCannotBeResolvedException(this, otherLine); |
425 | 475 |
|
426 | 476 |
//if (Math.cos(theta) == 0) { |
Also available in: Unified diff