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