Skip to content

Instantly share code, notes, and snippets.

@tamland
Last active August 29, 2015 13:56
Show Gist options
  • Save tamland/8953637 to your computer and use it in GitHub Desktop.
Save tamland/8953637 to your computer and use it in GitHub Desktop.
Find the minimum arbitrarily oriented bounding box from the convex hull
case class Point(x: Double, y: Double)
def orientedBoundingBox(hull: Seq[Point]) = {
val (area, rect) = (1 until hull.size).map { i =>
val (u, v) = (hull(i-1), hull(i))
val angle = math.atan((u.x - v.x) / (u.y - v.y))
val rotated = hull.map(rotate(_, angle))
val xs = rotated.map(_.x)
val ys = rotated.map(_.y)
val (x1, y1) = (xs.min, ys.min)
val (x2, y2) = (xs.max, ys.max)
val area = (x2 - x1) * (y2 - y1)
val p1 = rotate(Point(x1, y1), -angle)
val p2 = rotate(Point(x1, y2), -angle)
val p3 = rotate(Point(x2, y2), -angle)
val p4 = rotate(Point(x2, y1), -angle)
(area, (p1, p2, p3, p4))
}.minBy(_._1)
rect
}
def rotate(p: Point, angle: Double) = {
val cs = math.cos(angle)
val sn = math.sin(angle)
val x = p.x * cs - p.y * sn
val y = p.x * sn + p.y * cs
Point(x, y)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment