|
| 1 | +# Struct to hold an x, y position. A tuple would also be fine. |
| 2 | +struct Pos |
| 3 | + x::Float64 |
| 4 | + y::Float64 |
| 5 | +end |
| 6 | + |
| 7 | +# This returns a measure of how far "left" the vector is with a cross product |
| 8 | +function cross(point1::Pos, point2::Pos, point3::Pos) |
| 9 | + vec1 = Pos(point2.x - point1.x, point2.y - point1.y) |
| 10 | + vec2 = Pos(point3.x - point2.x, point3.y - point2.y) |
| 11 | + ret_angle = vec1.x*vec2.y - vec1.y*vec2.x |
| 12 | + return ret_angle*ret_angle |
| 13 | +end |
| 14 | + |
| 15 | +function jarvis_march(points::Vector{Pos}) |
| 16 | + hull = Vector{Pos}() |
| 17 | + |
| 18 | + # sorting array based on leftmost point |
| 19 | + sort!(points, by = item -> item.x) |
| 20 | + push!(hull, points[1]) |
| 21 | + |
| 22 | + i = 1 |
| 23 | + curr_point = points[2] |
| 24 | + |
| 25 | + # Find angle between points |
| 26 | + curr_product = cross(Pos(0,0), hull[1], curr_point) |
| 27 | + |
| 28 | + # We will hold a temp variable with the highest cross product as we iterate |
| 29 | + # through all the points and move our hull vector forward. |
| 30 | + while (curr_point != hull[1]) |
| 31 | + for point in points |
| 32 | + product = 0.0 |
| 33 | + |
| 34 | + # Special case for the first element when there is no hull[i-1] |
| 35 | + if (i == 1) |
| 36 | + if (hull[i] != point) |
| 37 | + product = cross(Pos(0,0), hull[i], point) |
| 38 | + end |
| 39 | + else |
| 40 | + if (hull[i] != point && hull[i-1] != point) |
| 41 | + product = cross(hull[i-1], hull[i], point) |
| 42 | + end |
| 43 | + end |
| 44 | + if (product > curr_product) |
| 45 | + curr_point = point |
| 46 | + curr_product = product |
| 47 | + end |
| 48 | + end |
| 49 | + |
| 50 | + # Pushing to hull, moving simulation forward and resetting the product |
| 51 | + push!(hull, curr_point) |
| 52 | + curr_product = 0 |
| 53 | + i += 1 |
| 54 | + end |
| 55 | + |
| 56 | + return hull |
| 57 | +end |
| 58 | + |
| 59 | +function main() |
| 60 | + |
| 61 | + # These points are chosen such that there is a clearly defined hull with |
| 62 | + # several interior points. As a note, these will be generated either |
| 63 | + # randomly or via some mesh in practice. |
| 64 | + points = [Pos(2,1.5), Pos(1, 1), Pos(2, 4), Pos(3, 1), Pos(2,2), Pos(2,0.5)] |
| 65 | + hull = jarvis_march(points) |
| 66 | + println(hull) |
| 67 | +end |
| 68 | + |
| 69 | +main() |
0 commit comments