@@ -4,39 +4,36 @@ object DelaunayTriangulation {
44 val n = arr(0 )
55 if (n < 3 ) return 0
66
7- val px = Array .tabulate(n)(i => arr(1 + 2 * i).toDouble)
8- val py = Array .tabulate(n)(i => arr(1 + 2 * i + 1 ).toDouble)
9-
10- val eps = 1e-9
11- var count = 0
12-
13- for (i <- 0 until n; j <- (i + 1 ) until n; k <- (j + 1 ) until n) {
14- val (ax, ay) = (px(i), py(i))
15- val (bx, by) = (px(j), py(j))
16- val (cx, cy) = (px(k), py(k))
17-
18- val d = 2.0 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by))
19- if (math.abs(d) >= eps) {
20- val ux = ((ax* ax + ay* ay) * (by - cy) +
21- (bx* bx + by* by) * (cy - ay) +
22- (cx* cx + cy* cy) * (ay - by)) / d
23- val uy = ((ax* ax + ay* ay) * (cx - bx) +
24- (bx* bx + by* by) * (ax - cx) +
25- (cx* cx + cy* cy) * (bx - ax)) / d
26-
27- val rSq = (ux - ax) * (ux - ax) + (uy - ay) * (uy - ay)
28-
29- val valid = (0 until n).forall { m =>
30- m == i || m == j || m == k || {
31- val distSq = (ux - px(m)) * (ux - px(m)) + (uy - py(m)) * (uy - py(m))
32- distSq >= rSq - eps
33- }
34- }
35-
36- if (valid) count += 1
7+ val points = Array .tabulate(n) { i =>
8+ (arr(1 + 2 * i), arr(1 + 2 * i + 1 ))
9+ }
10+
11+ def cross (o : (Int , Int ), a : (Int , Int ), b : (Int , Int )): Long =
12+ (a._1 - o._1).toLong * (b._2 - o._2) - (a._2 - o._2).toLong * (b._1 - o._1)
13+
14+ val base = points(0 )
15+ val allCollinear = points.drop(2 ).forall(point => cross(base, points(1 ), point) == 0L )
16+ if (allCollinear) return 0
17+
18+ val sorted = points.sortBy(point => (point._1, point._2))
19+
20+ val lower = scala.collection.mutable.ArrayBuffer [(Int , Int )]()
21+ for (point <- sorted) {
22+ while (lower.length >= 2 && cross(lower(lower.length - 2 ), lower(lower.length - 1 ), point) <= 0L ) {
23+ lower.remove(lower.length - 1 )
24+ }
25+ lower += point
26+ }
27+
28+ val upper = scala.collection.mutable.ArrayBuffer [(Int , Int )]()
29+ for (point <- sorted.reverse) {
30+ while (upper.length >= 2 && cross(upper(upper.length - 2 ), upper(upper.length - 1 ), point) <= 0L ) {
31+ upper.remove(upper.length - 1 )
3732 }
33+ upper += point
3834 }
3935
40- count
36+ val hullVertices = lower.length + upper.length - 2
37+ 2 * n - 2 - hullVertices
4138 }
4239}
0 commit comments