diff options
Diffstat (limited to 'src/main/scala/sims/geometry/Ray.scala')
-rw-r--r-- | src/main/scala/sims/geometry/Ray.scala | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/main/scala/sims/geometry/Ray.scala b/src/main/scala/sims/geometry/Ray.scala new file mode 100644 index 0000000..1cca8d5 --- /dev/null +++ b/src/main/scala/sims/geometry/Ray.scala @@ -0,0 +1,49 @@ +/* + * Simple Mechanics Simulator (SiMS) + * copyright (c) 2009 Jakob Odersky + * made available under the MIT License +*/ + +package sims.geometry + +import sims.math._ +import scala.math._ + +/**A ray. + * @param point a point on the ray + * @param direction this ray's directional vector + * @throws IllegalArgumentException if the directional vector is the null vector*/ +case class Ray(point: Vector2D, direction: Vector2D) { + + require(direction != Vector2D.Null, "A ray's direction cannot be given by a null vector!") + + /**Checks this ray and the given segment for intersection. + * @param s the segment to test for intersection*/ + def intersects(s: Segment) = { + val p1 = point + val p2 = point + direction + val p3 = s.vertex1 + val p4 = s.vertex2 + val d = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y) + val na = (p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x) + val nb = (p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x) + if (d == 0 && na == 0 && nb == 0) + true //lines are coincident + else if (d == 0) + false //parallel + else { + val ua = na / d + val ub = nb / d + (ub >= 0) && (ub <= 1) && (ua >= 0) + } + } + + /**Checks if this ray contains the point <code>p</code>.*/ + def contains(p: Vector2D) = { + val v = p - point + p == point || + Matrix22(direction, v).det == 0 && + signum(direction.x) == signum(v.x) && + signum(direction.y) == signum(v.y) + } +} |