blob: 80a63fb1143e08f3f3131a227677aef03b7669d9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/* _____ _ __ ________ ___ *\
** / ___/(_) |/ / ___/ |__ \ Simple Mechanics Simulator 2 **
** \__ \/ / /|_/ /\__ \ __/ / copyright (c) 2011 Jakob Odersky **
** ___/ / / / / /___/ / / __/ **
** /____/_/_/ /_//____/ /____/ **
\* */
package sims.collision
import scala.math._
import sims.math._
/**A ray.
* @param point starting point of this 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)
extends Linear
with Intersectable[Segment] {
/*def closest(point: Vector2D) = {
var t = ((point - this.point) dot (direction)) / (direction dot direction)
if (t < 0) t = 0
this.point + direction * t
}*/
def intersection(segment: Segment): Option[Vector2D] = {
val n = segment.leftNormal
// Handle case when two segments parallel
if ((n dot direction) == 0) None
else {
val t = (n dot (segment.point1 - point)) / (n dot direction)
val i = point + direction * t
if (0 <= t && (i - segment.point1).length <= segment.length) Some(i)
else None
}
/*
// Returns 2 times the signed triangle area. The result is positive if
// abc is ccw, negative if abc is cw, zero if abc is degenerate.
def signed2DTriArea(a: Vector2D, b: Vector2D, c: Vector2D) = {
(a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);
}
if (signed2DTriArea(point, point + direction, segment.point1) * signed2DTriArea(point, point + direction, segment.point2) < 0) {
val ab = segment.point2 - segment.point1
val ac = segment.point2 - point
val t = (ac.x * ab.y - ac.y * ab.x) / (direction.y * ab.x - direction.x - ab.y)
if (t >= 0) Some(point + direction * t) else None
} else None*/
}
/**Checks if this ray contains the point <code>p</code>.*/
def contains(p: Vector2D) = {
val v = p - point
p == point ||
v ~ direction &&
signum(direction.x) == signum(v.x) &&
signum(direction.y) == signum(v.y)
}
}
|