@Test public void intersectionTest() { Point point1 = new Point(1, 2); Point point3 = new Point(1, 1); Point point4 = new Point(2, -22); Point point5 = new Point(2, 22); Point point6 = new Point(2, 0); Point point7 = new Point(2, 5); LineSegment point1ToPoint3 = new LineSegment(point1, point3); LineSegment point1ToPoint1 = new LineSegment(point1, point1); LineSegment vertical = new LineSegment(point4, point5); Rectangle r1 = new Rectangle(0, 0, 5, 5); Rectangle r2 = new Rectangle(-22, -22, -11, -11); LineSegment s1 = point1ToPoint3.clipToRectangle(r1); Assert.assertEquals(point1ToPoint3, s1); LineSegment s2 = point1ToPoint1.clipToRectangle(r1); Assert.assertEquals(s2, point1ToPoint1); LineSegment s3 = point1ToPoint1.clipToRectangle(r2); Assert.assertEquals(s3, null); LineSegment verticalClipped = new LineSegment(point6, point7); LineSegment s4 = vertical.clipToRectangle(r1); Assert.assertEquals(s4, verticalClipped); LineSegment s5 = vertical.clipToRectangle(r2); Assert.assertEquals(s5, null); Rectangle r3 = new Rectangle(-1, -1, 1, 1); Point point8 = new Point(10, 10); Point point9 = new Point(-10, -10); Point point10 = new Point(-1, -1); Point point11 = new Point(1, 1); LineSegment s6 = new LineSegment(point8, point9); LineSegment s7 = s6.clipToRectangle(r3); LineSegment s8 = new LineSegment(point11, point10); Assert.assertEquals(s8, s7); LineSegment s6r = new LineSegment(point9, point8); LineSegment s7r = s6r.clipToRectangle(r3); LineSegment s8r = new LineSegment(point10, point11); Assert.assertEquals(s8r, s7r); }
public LineSegment clipToRectangle(Rectangle r) { Point a = this.start; Point b = this.end; int codeStart = code(r, a); int codeEnd = code(r, b); while (true) { if (0 == (codeStart | codeEnd)) { return new LineSegment(a, b); } else if (0 != (codeStart & codeEnd)) { return null; } else { double newX; double newY; int outsideCode = (0 != codeStart) ? codeStart : codeEnd; if (0 != (outsideCode & TOP)) { newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y); newY = r.top; } else if (0 != (outsideCode & BOTTOM)) { newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y); newY = r.bottom; } else if (0 != (outsideCode & RIGHT)) { newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x); newX = r.right; } else if (0 != (outsideCode & LEFT)) { newY = a.y + (b.y - a.y) * (r.left - a.x) / (b.x - a.x); newX = r.left; } else { throw new IllegalStateException("Should not get here"); } if (outsideCode == codeStart) { a = new Point(newX, newY); codeStart = code(r, a); } else { b = new Point(newX, newY); codeEnd = code(r, b); } } } }
LineSegment { public LineSegment clipToRectangle(Rectangle r) { Point a = this.start; Point b = this.end; int codeStart = code(r, a); int codeEnd = code(r, b); while (true) { if (0 == (codeStart | codeEnd)) { return new LineSegment(a, b); } else if (0 != (codeStart & codeEnd)) { return null; } else { double newX; double newY; int outsideCode = (0 != codeStart) ? codeStart : codeEnd; if (0 != (outsideCode & TOP)) { newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y); newY = r.top; } else if (0 != (outsideCode & BOTTOM)) { newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y); newY = r.bottom; } else if (0 != (outsideCode & RIGHT)) { newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x); newX = r.right; } else if (0 != (outsideCode & LEFT)) { newY = a.y + (b.y - a.y) * (r.left - a.x) / (b.x - a.x); newX = r.left; } else { throw new IllegalStateException("Should not get here"); } if (outsideCode == codeStart) { a = new Point(newX, newY); codeStart = code(r, a); } else { b = new Point(newX, newY); codeEnd = code(r, b); } } } } }
LineSegment { public LineSegment clipToRectangle(Rectangle r) { Point a = this.start; Point b = this.end; int codeStart = code(r, a); int codeEnd = code(r, b); while (true) { if (0 == (codeStart | codeEnd)) { return new LineSegment(a, b); } else if (0 != (codeStart & codeEnd)) { return null; } else { double newX; double newY; int outsideCode = (0 != codeStart) ? codeStart : codeEnd; if (0 != (outsideCode & TOP)) { newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y); newY = r.top; } else if (0 != (outsideCode & BOTTOM)) { newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y); newY = r.bottom; } else if (0 != (outsideCode & RIGHT)) { newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x); newX = r.right; } else if (0 != (outsideCode & LEFT)) { newY = a.y + (b.y - a.y) * (r.left - a.x) / (b.x - a.x); newX = r.left; } else { throw new IllegalStateException("Should not get here"); } if (outsideCode == codeStart) { a = new Point(newX, newY); codeStart = code(r, a); } else { b = new Point(newX, newY); codeEnd = code(r, b); } } } } LineSegment(Point start, Point end);  LineSegment(Point start, Point direction, double distance); }
LineSegment { public LineSegment clipToRectangle(Rectangle r) { Point a = this.start; Point b = this.end; int codeStart = code(r, a); int codeEnd = code(r, b); while (true) { if (0 == (codeStart | codeEnd)) { return new LineSegment(a, b); } else if (0 != (codeStart & codeEnd)) { return null; } else { double newX; double newY; int outsideCode = (0 != codeStart) ? codeStart : codeEnd; if (0 != (outsideCode & TOP)) { newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y); newY = r.top; } else if (0 != (outsideCode & BOTTOM)) { newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y); newY = r.bottom; } else if (0 != (outsideCode & RIGHT)) { newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x); newX = r.right; } else if (0 != (outsideCode & LEFT)) { newY = a.y + (b.y - a.y) * (r.left - a.x) / (b.x - a.x); newX = r.left; } else { throw new IllegalStateException("Should not get here"); } if (outsideCode == codeStart) { a = new Point(newX, newY); codeStart = code(r, a); } else { b = new Point(newX, newY); codeEnd = code(r, b); } } } } LineSegment(Point start, Point end);  LineSegment(Point start, Point direction, double distance); double angleTo(LineSegment other); LineSegment clipToRectangle(Rectangle r); @Override boolean equals(Object obj); @Override int hashCode(); boolean intersectsRectangle(Rectangle r, boolean bias); double length(); Point pointAlongLineSegment(double distance); LineSegment reverse(); LineSegment subSegment(double offset, double length); @Override String toString(); }
LineSegment { public LineSegment clipToRectangle(Rectangle r) { Point a = this.start; Point b = this.end; int codeStart = code(r, a); int codeEnd = code(r, b); while (true) { if (0 == (codeStart | codeEnd)) { return new LineSegment(a, b); } else if (0 != (codeStart & codeEnd)) { return null; } else { double newX; double newY; int outsideCode = (0 != codeStart) ? codeStart : codeEnd; if (0 != (outsideCode & TOP)) { newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y); newY = r.top; } else if (0 != (outsideCode & BOTTOM)) { newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y); newY = r.bottom; } else if (0 != (outsideCode & RIGHT)) { newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x); newX = r.right; } else if (0 != (outsideCode & LEFT)) { newY = a.y + (b.y - a.y) * (r.left - a.x) / (b.x - a.x); newX = r.left; } else { throw new IllegalStateException("Should not get here"); } if (outsideCode == codeStart) { a = new Point(newX, newY); codeStart = code(r, a); } else { b = new Point(newX, newY); codeEnd = code(r, b); } } } } LineSegment(Point start, Point end);  LineSegment(Point start, Point direction, double distance); double angleTo(LineSegment other); LineSegment clipToRectangle(Rectangle r); @Override boolean equals(Object obj); @Override int hashCode(); boolean intersectsRectangle(Rectangle r, boolean bias); double length(); Point pointAlongLineSegment(double distance); LineSegment reverse(); LineSegment subSegment(double offset, double length); @Override String toString(); final Point start; final Point end; }