test_class.file: kendzi-math-geometry/src/test/java/kendzi/math/geometry/ray/RayUtilTest.java
test_class.identifier: RayUtilTest
test_case.body: @Test
      public void testIntersectRays2d_1() {
          Ray2d r1 = new Ray2d(new Point2d(0, 0), new Vector2d(1, 0));
          Ray2d r2 = new Ray2d(new Point2d(0, -1), new Vector2d(1, 1));
  
          IntersectPoints intersectRays2d = RayUtil.intersectRays2d(r1, r2);
          assertPoint(1, 0, intersectRays2d.getIntersect());
      }
test_case.class_method_signature: RayUtilTest.testIntersectRays2d_1()
test_case.full_signature: @Test public void testIntersectRays2d_1()
test_case.identifier: testIntersectRays2d_1
test_case.invocations: intersectRays2d assertPoint getIntersect
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testIntersectRays2d_1()
focal_class.declarator: SMALL_NUM = 0.00000001
focal_class.modifier: static final
focal_class.original_string: static final double SMALL_NUM = 0.00000001;
focal_class.type: double
focal_class.var_name: SMALL_NUM
focal_class.declarator: EMPTY = new IntersectPoints()
focal_class.modifier: static final
focal_class.original_string: static final IntersectPoints EMPTY = new IntersectPoints();
focal_class.type: IntersectPoints
focal_class.var_name: EMPTY
focal_class.file: kendzi-math-geometry/src/main/java/kendzi/math/geometry/ray/RayUtil.java
focal_class.identifier: RayUtil
focal_class.class_method_signature: RayUtil.RayUtil()
focal_class.full_signature: private  RayUtil()
focal_class.identifier: RayUtil
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.signature:  RayUtil()
focal_class.class_method_signature: RayUtil.isPointOnRay(Point2d point, Ray2d ray, double epsilon)
focal_class.full_signature: public static boolean isPointOnRay(Point2d point, Ray2d ray, double epsilon)
focal_class.identifier: isPointOnRay
focal_class.modifiers: public static
focal_class.parameters: (Point2d point, Ray2d ray, double epsilon)
focal_class.return: boolean
focal_class.signature: boolean isPointOnRay(Point2d point, Ray2d ray, double epsilon)
focal_class.class_method_signature: RayUtil.intersectRays2d(Ray2d r1, Ray2d r2)
focal_class.full_signature: public static IntersectPoints intersectRays2d(Ray2d r1, Ray2d r2)
focal_class.identifier: intersectRays2d
focal_class.modifiers: public static
focal_class.parameters: (Ray2d r1, Ray2d r2)
focal_class.return: IntersectPoints
focal_class.signature: IntersectPoints intersectRays2d(Ray2d r1, Ray2d r2)
focal_class.class_method_signature: RayUtil.inCollinearRay(Point2d p, Point2d rayStart, Vector2d rayDirection)
focal_class.full_signature: private static boolean inCollinearRay(Point2d p, Point2d rayStart, Vector2d rayDirection)
focal_class.identifier: inCollinearRay
focal_class.modifiers: private static
focal_class.parameters: (Point2d p, Point2d rayStart, Vector2d rayDirection)
focal_class.return: boolean
focal_class.signature: boolean inCollinearRay(Point2d p, Point2d rayStart, Vector2d rayDirection)
focal_class.class_method_signature: RayUtil.inSegment(Point2d P, Point2d segmentP0, Point2d segmentP1)
focal_class.full_signature: static boolean inSegment(Point2d P, Point2d segmentP0, Point2d segmentP1)
focal_class.identifier: inSegment
focal_class.modifiers: static
focal_class.parameters: (Point2d P, Point2d segmentP0, Point2d segmentP1)
focal_class.return: boolean
focal_class.signature: boolean inSegment(Point2d P, Point2d segmentP0, Point2d segmentP1)
focal_class.class_method_signature: RayUtil.dot(Vector2d u, Vector2d v)
focal_class.full_signature: private static double dot(Vector2d u, Vector2d v)
focal_class.identifier: dot
focal_class.modifiers: private static
focal_class.parameters: (Vector2d u, Vector2d v)
focal_class.return: double
focal_class.signature: double dot(Vector2d u, Vector2d v)
focal_class.class_method_signature: RayUtil.perp(Vector2d u, Vector2d v)
focal_class.full_signature: private static double perp(Vector2d u, Vector2d v)
focal_class.identifier: perp
focal_class.modifiers: private static
focal_class.parameters: (Vector2d u, Vector2d v)
focal_class.return: double
focal_class.signature: double perp(Vector2d u, Vector2d v)
focal_method.body: public static IntersectPoints intersectRays2d(Ray2d r1, Ray2d r2) {
  
          Point2d s1p0 = r1.A;
          Point2d s1p1 = new Point2d(r1.A);
          s1p1.add(r1.U);
  
          Point2d s2p0 = r2.A;
          Point2d s2p1 = new Point2d(r2.A);
          s2p1.add(r2.U);
  
          Vector2d u = r1.U;
          Vector2d v = r2.U;
  
          Vector2d w = new Vector2d();
          w.sub(s1p0, s2p0);
  
          double d = perp(u, v);
  
          // test if they are parallel (includes either being a point)
          if (Math.abs(d) < SMALL_NUM) { // S1 and S2 are parallel
              if (perp(u, w) != 0 || perp(v, w) != 0) {
                  // return 0;
                  // they are NOT collinear
                  return EMPTY;
              }
              // they are collinear or degenerate
              // check if they are degenerate points
              double du = dot(u, u);
              double dv = dot(v, v);
              if (du == 0 && dv == 0) {
                  // both segments are points
                  if (s1p0 != s2p0) {
  
                      // return 0;
                      return EMPTY;
                  }
                  Point2d I0 = s1p0;
                  // they are the same point
                  // return 1;
                  return new IntersectPoints(I0);
              }
              if (du == 0) {
                  // S1 is a single point
                  if (!inCollinearRay(s1p0, s2p0, v)) {
                      // return 0;
                      return EMPTY;
                  }
                  Point2d I0 = s1p0;
                  // return 1;
                  return new IntersectPoints(I0);
              }
              if (dv == 0) {
                  // S2 a single point
                  if (!inCollinearRay(s2p0, s1p0, u)) {
                      // return 0;
                      return EMPTY;
                  }
                  Point2d I0 = s2p0;
                  // return 1;
                  return new IntersectPoints(I0);
              }
              // they are collinear segments - get overlap (or not)
              double t0, t1;
              // endpoints of S1 in eqn for S2
              Vector2d w2 = new Vector2d();
              w2.sub(s1p1, s2p0);
              if (v.x != 0) {
                  t0 = w.x / v.x;
                  t1 = w2.x / v.x;
              } else {
                  t0 = w.y / v.y;
                  t1 = w2.y / v.y;
              }
              if (t0 > t1) {
                  // must have t0 smaller than t1
                  double t = t0;
                  t0 = t1;
                  t1 = t; // swap if not
              }
              if (/*t0 > 1 ||*/ t1 < 0) {
                  // return 0; // NO overlap
                  return EMPTY;
              }
  
              // clip to min 0
              t0 = t0 < 0 ? 0 : t0;
              // clip to max 1
              //t1 = t1 > 1 ? 1 : t1;
  
              if (t0 == t1) {
                  // intersect is a point
  
                  // I0 = S2_P0 + t0 * v;
                  Point2d I0 = new Point2d(v);
                  I0.scale(t0);
                  I0.add(s2p0);
  
                  // return 1;
                  return new IntersectPoints(I0);
              }
  
              // they overlap in a valid subsegment
  
              // I0 = S2_P0 + t0 * v;
              Point2d I0 = new Point2d(v);
              I0.scale(t0);
              I0.add(s2p0);
  
              // I1 = S2_P0 + t1 * v;
              Point2d I1 = new Point2d(v);
              I1.scale(t1);
              I1.add(s2p0);
  
              // return 2;
              return new IntersectPoints(I0, I1);
          }
  
          // the segments are skew and may intersect in a point
          // get the intersect parameter for S1
          double sI = perp(v, w) / d;
          if (sI < 0/* || sI > 1 */) {
              // return 0;
              return EMPTY;
          }
  
          // get the intersect parameter for S2
          double tI = perp(u, w) / d;
          if (tI < 0 /* || tI > 1 */) {
              // return 0;
              return EMPTY;
          }
  
          // I0 = S1_P0 + sI * u; // compute S1 intersect point
          Point2d I0 = new Point2d(u);
          I0.scale(sI);
          I0.add(s1p0);
          // return 1;
          return new IntersectPoints(I0);
      }
focal_method.class_method_signature: RayUtil.intersectRays2d(Ray2d r1, Ray2d r2)
focal_method.full_signature: public static IntersectPoints intersectRays2d(Ray2d r1, Ray2d r2)
focal_method.identifier: intersectRays2d
focal_method.invocations: add add sub perp abs perp perp dot dot inCollinearRay inCollinearRay sub scale add scale add scale add perp perp scale add
focal_method.modifiers: public static
focal_method.parameters: (Ray2d r1, Ray2d r2)
focal_method.return: IntersectPoints
focal_method.signature: IntersectPoints intersectRays2d(Ray2d r1, Ray2d r2)