Newer
Older
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
case class Point(
x: Double,
y: Double
):
def +(that: Point) = Point(this.x + that.x, this.y + that.y)
def unary_- : Point = Point(-x,-y)
def -(that: Point) = this + (- that)
def *(scalar: Double) = Point(x*scalar,y*scalar)
def magnitude: Double = Math.sqrt(Math.pow(x,2) + Math.pow(y,2))
def phi: Double = Math.atan2(y,x)
def normalized: Point = Point(Math.cos(phi),Math.sin(phi))
object Point:
def distance(a: Point, b: Point): Double = (a - b).magnitude
case class Path(
color: String,
width: Int,
points: Vector[Point]
):
def append(x: Double, y: Double): Path = {
if (points.length > 1 && Point.distance(points.last,points.init.last) <= width * 2)
copy(points = points.init :+ Point(x,y))
else
copy(points = points :+ Point(x,y))
}
val scale = 0.5
lazy val controlPoints: Seq[Point] = (for (i <- 0 until points.length) yield {
if (i == 0) {
val p1 = points(i)
val p2 = points(i+1)
val tangent = p2 - p1;
val q1 = p1 + tangent * scale;
Seq(p1,q1)
} else if (i == points.length - 1) {
val p0 = points(i - 1)
val p1 = points(i)
val tangent = (p1 - p0);
val q0 = p1 - tangent * scale;
Seq(q0,p1)
} else {
val p0 = points(i - 1)
val p1 = points(i)
val p2 = points(i + 1)
val tangent = (p2 - p0).normalized;
val q0 = p1 - tangent * scale * (p1 - p0).magnitude;
val q1 = p1 + tangent * scale * (p2 - p1).magnitude;
Seq(q0,p1,q1)
}
}).flatten
def hits(x: Double, y: Double): Boolean = points.exists(p => Point.distance(p,Point(x,y)) <= width)
def isEmpty: Boolean = points.length < 2