Skip to content

Instantly share code, notes, and snippets.

@adusak
Last active August 29, 2015 14:17
Show Gist options
  • Select an option

  • Save adusak/22e747719f4538c28b7e to your computer and use it in GitHub Desktop.

Select an option

Save adusak/22e747719f4538c28b7e to your computer and use it in GitHub Desktop.
Generates points and creates their convex hull with the option to do if for all the points generated
from operator import itemgetter
from python.common import line as ln
from python.common.polygon import Polygon
from python.common.svg import Svg
from python.less5.generate_points import generate_points
def less(a, b):
return a < b
def more(a, b):
return a > b
def get_hull_points(hull_points, all_points, left_to_right):
offset = 180 if left_to_right else 360
compare_fn = less if left_to_right else more
for point in hull_points:
ln1 = ln.Line(point[0], point[1], point[0], point[1] + 1)
true_next = None
angle_min = None
for next_p in all_points:
if compare_fn(next_p[0], point[0]):
continue
ln2 = ln.Line(point[0], point[1], next_p[0], next_p[1])
angle = ln.line_angle(ln1, ln2, offset)
if angle_min is None or compare_fn(angle_min, angle):
angle_min = angle
true_next = next_p
if true_next is None:
break
all_points.remove(true_next)
hull_points.append(true_next)
return hull_points
def convex_hull(number_of_points, canvas_size, onion=False, gauss=False):
svg = Svg()
points = generate_points(number_of_points, canvas_size, gauss)
for point in points:
svg.add_circle(point)
run_length = len(points) if onion else 1
while run_length > 0:
points_on_x = sorted(points, key=itemgetter(0))
leftmost_p = points_on_x[0]
rightmost_p = points_on_x[-1]
svg.add_circle(leftmost_p, fill_color=(255, 0, 0), stroke_width=0.25, r=1)
svg.add_circle(rightmost_p, fill_color=(255, 0, 0), stroke_width=0.25, r=1)
hull_points_1 = get_hull_points([leftmost_p], points, True)
hull_points_2 = get_hull_points([rightmost_p], points, False)
hull_points = hull_points_1 + hull_points_2
hull_points.append(hull_points[0])
polygon = Polygon(hull_points)
polygon.draw_to_svg(svg)
points = [x for x in points if x not in hull_points]
run_length = len(points) if onion else 0
svg.save("convex_hull" + ("_onion" if onion else "") +
("_gauss" if gauss else ""))
# convex_hull(1000, (1920, 1060), onion=True, gauss=False) # Obr. 1
# convex_hull(1000, (1920, 1060), onion=True, gauss=True) # Obr. 2
# convex_hull(1000, (1920, 1060), onion=False, gauss=False) # Obr. 3
# convex_hull(1000, (1920, 1060), onion=False, gauss=True) # Obr. 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment