1 /*
2  * Copyright (c) 2016 Vivid Solutions.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
8  * and the Eclipse Distribution License is available at
9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12 package org.locationtech.jts.geom;
13 
14 import org.locationtech.jts.io.WKTReader;
15 
16 import junit.framework.TestCase;
17 import junit.textui.TestRunner;
18 
19 
20 /**
21  * Test named predicate short-circuits
22  */
23 /**
24  * @version 1.7
25  */
26 public class LineSegmentTest extends TestCase {
27 
28   WKTReader rdr = new WKTReader();
29 
main(String args[])30   public static void main(String args[]) {
31     TestRunner.run(LineSegmentTest.class);
32   }
33 
LineSegmentTest(String name)34   public LineSegmentTest(String name) { super(name); }
35 
36   private static double ROOT2 = Math.sqrt(2);
37 
testProjectionFactor()38   public void testProjectionFactor()
39   {
40     // zero-length line
41     LineSegment seg = new LineSegment(10, 0, 10, 0);
42     assertTrue(Double.isNaN(seg.projectionFactor(new Coordinate(11, 0))));
43 
44     LineSegment seg2 = new LineSegment(10, 0, 20, 0);
45     assertTrue(seg2.projectionFactor(new Coordinate(11, 0)) == 0.1);
46   }
47 
testLineIntersection()48   public void testLineIntersection() {
49     // simple case
50     checkLineIntersection(
51         0,0,  10,10,
52         0,10, 10,0,
53         5,5);
54 
55     //Almost collinear - See JTS GitHub issue #464
56     checkLineIntersection(
57         35613471.6165017, 4257145.306132293, 35613477.7705378, 4257160.528222711,
58         35613477.77505724, 4257160.539653536, 35613479.85607389, 4257165.92369170,
59         35613477.772841461, 4257160.5339209242 );
60   }
61 
62   private static final double MAX_ABS_ERROR_INTERSECTION = 1e-5;
63 
checkLineIntersection(double p1x, double p1y, double p2x, double p2y, double q1x, double q1y, double q2x, double q2y, double expectedx, double expectedy)64   private void checkLineIntersection(double p1x, double p1y, double p2x, double p2y,
65       double q1x, double q1y, double q2x, double q2y,
66       double expectedx, double expectedy) {
67     LineSegment seg1 = new LineSegment(p1x, p1y, p2x, p2y);
68     LineSegment seg2 = new LineSegment(q1x, q1y, q2x, q2y);
69 
70     Coordinate actual = seg1.lineIntersection(seg2);
71     Coordinate expected = new Coordinate( expectedx, expectedy );
72     double dist = actual.distance(expected);
73     //System.out.println("Expected: " + expected + "  Actual: " + actual + "  Dist = " + dist);
74     assertTrue(dist <= MAX_ABS_ERROR_INTERSECTION);
75   }
76 
testOffset()77   public void testOffset() throws Exception
78   {
79     checkOffset(0, 0, 10, 10, 0.0, ROOT2, -1, 1);
80     checkOffset(0, 0, 10, 10, 0.0, -ROOT2, 1, -1);
81 
82     checkOffset(0, 0, 10, 10, 1.0, ROOT2, 9, 11);
83     checkOffset(0, 0, 10, 10, 0.5, ROOT2, 4, 6);
84 
85     checkOffset(0, 0, 10, 10, 0.5, -ROOT2, 6, 4);
86     checkOffset(0, 0, 10, 10, 0.5, -ROOT2, 6, 4);
87 
88     checkOffset(0, 0, 10, 10, 2.0, ROOT2, 19, 21);
89     checkOffset(0, 0, 10, 10, 2.0, -ROOT2, 21, 19);
90 
91     checkOffset(0, 0, 10, 10, 2.0, 5 * ROOT2, 15, 25);
92     checkOffset(0, 0, 10, 10, -2.0, 5 * ROOT2, -25, -15);
93 
94   }
95 
checkOffset(double x0, double y0, double x1, double y1, double segFrac, double offset, double expectedX, double expectedY)96   void checkOffset(double x0, double y0, double x1, double y1, double segFrac, double offset,
97   		double expectedX, double expectedY)
98   {
99   	LineSegment seg = new LineSegment(x0, y0, x1, y1);
100   	Coordinate p = seg.pointAlongOffset(segFrac, offset);
101 
102   	assertTrue(equalsTolerance(new Coordinate(expectedX, expectedY), p, 0.000001));
103   }
104 
equalsTolerance(Coordinate p0, Coordinate p1, double tolerance)105   public static boolean equalsTolerance(Coordinate p0, Coordinate p1, double tolerance)
106   {
107   	if (Math.abs(p0.x - p1.x) > tolerance) return false;
108   	if (Math.abs(p0.y - p1.y) > tolerance) return false;
109   	return true;
110   }
111 
testReflect()112   public void testReflect() {
113     checkReflect(0, 0, 10, 10, 1,2, 2 ,1 );
114     checkReflect(0, 1, 10, 1, 1, 2, 1, 0 );
115   }
116 
checkReflect(double x0, double y0, double x1, double y1, double x, double y, double expectedX, double expectedY)117   void checkReflect(double x0, double y0, double x1, double y1, double x, double y,
118       double expectedX, double expectedY)
119   {
120     LineSegment seg = new LineSegment(x0, y0, x1, y1);
121     Coordinate p = seg.reflect(new Coordinate(x, y));
122     assertTrue(equalsTolerance(new Coordinate(expectedX, expectedY), p, 0.000001));
123   }
124 
testOrientationIndexCoordinate()125   public void testOrientationIndexCoordinate()
126   {
127   	LineSegment seg = new LineSegment(0, 0, 10, 10);
128   	checkOrientationIndex(seg, 10, 11, 1);
129   	checkOrientationIndex(seg, 10, 9, -1);
130 
131   	checkOrientationIndex(seg, 11, 11, 0);
132 
133   	checkOrientationIndex(seg, 11, 11.0000001, 1);
134   	checkOrientationIndex(seg, 11, 10.9999999, -1);
135 
136   	checkOrientationIndex(seg, -2, -1.9999999, 1);
137   	checkOrientationIndex(seg, -2, -2.0000001, -1);
138   }
139 
testOrientationIndexSegment()140   public void testOrientationIndexSegment()
141   {
142   	LineSegment seg = new LineSegment(100, 100, 110, 110);
143 
144   	checkOrientationIndex(seg, 100, 101, 105, 106, 1);
145   	checkOrientationIndex(seg, 100, 99, 105, 96, -1);
146 
147   	checkOrientationIndex(seg, 200, 200, 210, 210, 0);
148 
149   }
150 
checkOrientationIndex(double x0, double y0, double x1, double y1, double px, double py, int expectedOrient)151   void checkOrientationIndex(double x0, double y0, double x1, double y1, double px, double py,
152   		int expectedOrient)
153   {
154   	LineSegment seg = new LineSegment(x0, y0, x1, y1);
155   	checkOrientationIndex(seg, px, py, expectedOrient);
156   }
157 
checkOrientationIndex(LineSegment seg, double px, double py, int expectedOrient)158   void checkOrientationIndex(LineSegment seg,
159   		double px, double py,
160   		int expectedOrient)
161   {
162   	Coordinate p = new Coordinate(px, py);
163   	int orient = seg.orientationIndex(p);
164   	assertTrue(orient == expectedOrient);
165   }
166 
checkOrientationIndex(LineSegment seg, double s0x, double s0y, double s1x, double s1y, int expectedOrient)167   void checkOrientationIndex(LineSegment seg,
168   		double s0x, double s0y,
169   		double s1x, double s1y,
170   		int expectedOrient)
171   {
172   	LineSegment seg2 = new LineSegment(s0x, s0y, s1x, s1y);
173   	int orient = seg.orientationIndex(seg2);
174   	assertTrue(orient == expectedOrient);
175   }
176 
177 
178 }
179