// Path: kendzi-math-geometry/src/main/java/kendzi/math/geometry/point/Vector2dUtil.java
// public class Vector2dUtil {
// 
//     private static double EPSILON = 0.00000001;
// 
//     public static Vector2d orthogonalLeft(Vector2d v) {
//         return new Vector2d(-v.y, v.x);
//     }
// 
//     public static Vector2d orthogonalRight(Vector2d v) {
//         return new Vector2d(v.y, -v.x);
//     }
// 
//     public static Vector2d bisector(Point2d p1, Point2d p2, Point2d p3) { // left
//         // XXX rename to bisectorLeft
//         return Vector2dUtil.bisector(Vector2dUtil.fromTo(p1, p2), Vector2dUtil.fromTo(p2, p3));
//     }
// 
//     public static Vector2d bisector(Vector2d v1, Vector2d v2) {
//         // XXX rename to bisectorLeft
//         Vector2d norm1 = new Vector2d(v1);
//         norm1.normalize();
// 
//         Vector2d norm2 = new Vector2d(v2);
//         norm2.normalize();
// 
//         return bisectorNormalized(norm1, norm2);
//     }
// 
//     public static Vector2d bisectorNormalized(Vector2d norm1, Vector2d norm2) {
//         Vector2d e1v = orthogonalLeft(norm1);
//         Vector2d e2v = orthogonalLeft(norm2);
// 
//         // 90 - 180 || 180 - 270
//         // if (norm1.dot(e2v) <= 0 && ) { //XXX >= !!
//         if (norm1.dot(norm2) > 0) {
// 
//             e1v.add(e2v);
//             return e1v;
// 
//         }
// 
//         // 0 - 180
//         Vector2d ret = new Vector2d(norm1);
//         ret.negate();
//         ret.add(norm2);
// 
//         if (e1v.dot(norm2) < 0) {
//             // 270 - 360
//             ret.negate();
//         }
//         return ret;
//     }
// 
//     private static boolean equalsEpsilon(double pNumber) {
//         if ((pNumber < 0 ? -pNumber : pNumber) > EPSILON) {
//             return false;
//         }
//         return false;
// 
//     }
// 
//     /**
//      * Cross product for 2d is same as doc
//      * 
//      * @param u
//      * @param v
//      * @return
//      * @see {http://mathworld.wolfram.com/CrossProduct.html}
//      */
//     public static double cross(Tuple2d u, Tuple2d v) {
//         return u.x * v.y - u.y * v.x;
//     }
// 
//     public static Vector2d fromTo(Point2d begin, Point2d end) {
//         return new Vector2d(end.x - begin.x, end.y - begin.y);
//     }
// 
//     public static Vector2d negate(Vector2d vector) {
//         return new Vector2d(-vector.x, -vector.y);
//     }
// 
// }


import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;
import kendzi.math.geometry.point.Vector2dUtil;

package kendzi.math.geometry.line;



public class LineSegment2d {

    Point2d begin;
    Point2d end;

    /**
     * XXX is need ?
     */
    boolean openBegin;
    /**
     * XXX is need ?
     */
    boolean openEnd;

    public LineSegment2d(Point2d begin, Point2d end) {
        super();
        this.begin = begin;
        this.end = end;
    }

    /** Collision point of line and line segment.
     * @param x1 line segment begin point x
     * @param y1 line segment begin point y
     * @param x2 line segment end point x
     * @param y2 line segment end point y
     *
     * @param A line in linear form parameter A
     * @param B line in linear form parameter B
     * @param C line in linear form parameter C
     *
     * XXX better name is intersects ?!
     * @return collision point
     */
    public static Point2d collide(double x1, double y1, double x2, double y2, double A, double B, double C
            ) {

        // XXX TODO FIXME when end of line segment is lies on line

        if (det(x1, y1, A, B, C) * det(x2, y2, A, B, C) < 0) {

            double A2 = y1 - y2;
            double B2 = x2 - x1;
            double C2 = x1 * y2 - x2 * y1;

            return LineLinear2d.collide(A, B, C, A2, B2, C2);
        }
        return null;
    }

    public Point2d intersect(LineSegment2d lineSegment) {

// Path: kendzi-math-geometry/src/main/java/kendzi/math/geometry/point/Vector2dUtil.java
// public class Vector2dUtil {
// 
//     private static double EPSILON = 0.00000001;
// 
//     public static Vector2d orthogonalLeft(Vector2d v) {
//         return new Vector2d(-v.y, v.x);
//     }
// 
//     public static Vector2d orthogonalRight(Vector2d v) {
//         return new Vector2d(v.y, -v.x);
//     }
// 
//     public static Vector2d bisector(Point2d p1, Point2d p2, Point2d p3) { // left
//         // XXX rename to bisectorLeft
//         return Vector2dUtil.bisector(Vector2dUtil.fromTo(p1, p2), Vector2dUtil.fromTo(p2, p3));
//     }
// 
//     public static Vector2d bisector(Vector2d v1, Vector2d v2) {
//         // XXX rename to bisectorLeft
//         Vector2d norm1 = new Vector2d(v1);
//         norm1.normalize();
// 
//         Vector2d norm2 = new Vector2d(v2);
//         norm2.normalize();
// 
//         return bisectorNormalized(norm1, norm2);
//     }
// 
//     public static Vector2d bisectorNormalized(Vector2d norm1, Vector2d norm2) {
//         Vector2d e1v = orthogonalLeft(norm1);
//         Vector2d e2v = orthogonalLeft(norm2);
// 
//         // 90 - 180 || 180 - 270
//         // if (norm1.dot(e2v) <= 0 && ) { //XXX >= !!
//         if (norm1.dot(norm2) > 0) {
// 
//             e1v.add(e2v);
//             return e1v;
// 
//         }
// 
//         // 0 - 180
//         Vector2d ret = new Vector2d(norm1);
//         ret.negate();
//         ret.add(norm2);
// 
//         if (e1v.dot(norm2) < 0) {
//             // 270 - 360
//             ret.negate();
//         }
//         return ret;
//     }
// 
//     private static boolean equalsEpsilon(double pNumber) {
//         if ((pNumber < 0 ? -pNumber : pNumber) > EPSILON) {
//             return false;
//         }
//         return false;
// 
//     }
// 
//     /**
//      * Cross product for 2d is same as doc
//      * 
//      * @param u
//      * @param v
//      * @return
//      * @see {http://mathworld.wolfram.com/CrossProduct.html}
//      */
//     public static double cross(Tuple2d u, Tuple2d v) {
//         return u.x * v.y - u.y * v.x;
//     }
// 
//     public static Vector2d fromTo(Point2d begin, Point2d end) {
//         return new Vector2d(end.x - begin.x, end.y - begin.y);
//     }
// 
//     public static Vector2d negate(Vector2d vector) {
//         return new Vector2d(-vector.x, -vector.y);
//     }
// 
// }


// Path: kendzi-math-geometry/src/main/java/kendzi/math/geometry/line/LineSegment2d.java
import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;
import kendzi.math.geometry.point.Vector2dUtil;

package kendzi.math.geometry.line;



public class LineSegment2d {

    Point2d begin;
    Point2d end;

    /**
     * XXX is need ?
     */
    boolean openBegin;
    /**
     * XXX is need ?
     */
    boolean openEnd;

    public LineSegment2d(Point2d begin, Point2d end) {
        super();
        this.begin = begin;
        this.end = end;
    }

    /** Collision point of line and line segment.
     * @param x1 line segment begin point x
     * @param y1 line segment begin point y
     * @param x2 line segment end point x
     * @param y2 line segment end point y
     *
     * @param A line in linear form parameter A
     * @param B line in linear form parameter B
     * @param C line in linear form parameter C
     *
     * XXX better name is intersects ?!
     * @return collision point
     */
    public static Point2d collide(double x1, double y1, double x2, double y2, double A, double B, double C
            ) {

        // XXX TODO FIXME when end of line segment is lies on line

        if (det(x1, y1, A, B, C) * det(x2, y2, A, B, C) < 0) {

            double A2 = y1 - y2;
            double B2 = x2 - x1;
            double C2 = x1 * y2 - x2 * y1;

            return LineLinear2d.collide(A, B, C, A2, B2, C2);
        }
        return null;
    }

    public Point2d intersect(LineSegment2d lineSegment) {

        Vector2d v1 = Vector2dUtil.fromTo(this.begin, this.end);
