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)) {
                // both points are inside, intersection is the computed line
                return new LineSegment(a, b);
            } else if (0 != (codeStart & codeEnd)) {
                // both points are either below, above, left or right of the box, no intersection
                return null;
            } else {
                double newX;
                double newY;
                // At least one endpoint is outside the clip rectangle; pick it.
                int outsideCode = (0 != codeStart) ? codeStart : codeEnd;

                if (0 != (outsideCode & TOP)) {
                    // point is above the clip rectangle
                    newX = a.x + (b.x - a.x) * (r.top - a.y) / (b.y - a.y);
                    newY = r.top;
                } else if (0 != (outsideCode & BOTTOM)) {
                    // point is below the clip rectangle
                    newX = a.x + (b.x - a.x) * (r.bottom - a.y) / (b.y - a.y);
                    newY = r.bottom;
                } else if (0 != (outsideCode & RIGHT)) {
                    // point is to the right of clip rectangle
                    newY = a.y + (b.y - a.y) * (r.right - a.x) / (b.x - a.x);
                    newX = r.right;
                } else if (0 != (outsideCode & LEFT)) {
                    // point is to the left of clip rectangle
                    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");
                }
                // Now we move outside point to intersection point to clip
                // and get ready for next pass.
                if (outsideCode == codeStart) {
                    a = new Point(newX, newY);
                    codeStart = code(r, a);
                } else {
                    b = new Point(newX, newY);
                    codeEnd = code(r, b);
                }
            }
        }
    }
@Test
    public void intersectionTest() {
        Point point1 = new Point(1, 2);
        // Point point2 = 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);
    }