/
laser_clipper.py
112 lines (82 loc) · 4.02 KB
/
laser_clipper.py
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# laser_clipper.py
"""polygon math using Clipper library for laser cutting"""
# http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
import pyclipper
SCALING_FACTOR = 1000
def merge_loops(loops):
"""merges multiple loops into a union"""
if len(loops) < 1:
return (loops)
union = [loops[0]]
for loopindex in range(len(loops)):
union = get_union(union, [loops[loopindex]])
return union
def get_difference(first, second):
"""Takes two list of loops (list of (x,y) points), and returns the difference"""
second = merge_loops(second)
if second == []:
return first
clipper = pyclipper.Pyclipper()
scaled_first = pyclipper.scale_to_clipper(first, SCALING_FACTOR)
scaled_second = pyclipper.scale_to_clipper(second, SCALING_FACTOR)
clipper.AddPaths(scaled_first, pyclipper.PT_SUBJECT)
clipper.AddPaths(scaled_second, pyclipper.PT_CLIP)
scaled_difference = clipper.Execute(pyclipper.CT_DIFFERENCE)
difference = pyclipper.scale_from_clipper(
scaled_difference, SCALING_FACTOR)
return difference
def get_intersection(first, second):
"""Takes two list of loops(list of(x, y) points), and returns the intersection"""
clipper = pyclipper.Pyclipper() # pylint: disable=c-extension-no-member
scaled_first = pyclipper.scale_to_clipper(first, SCALING_FACTOR)
scaled_second = pyclipper.scale_to_clipper(second, SCALING_FACTOR)
clipper.AddPaths(scaled_first, pyclipper.PT_SUBJECT)
clipper.AddPaths(scaled_second, pyclipper.PT_CLIP)
scaled_intersection = clipper.Execute(pyclipper.CT_INTERSECTION)
intersection = pyclipper.scale_from_clipper(
scaled_intersection, SCALING_FACTOR)
return intersection
def get_union(first, second):
"""Takes two list of loops(list of(x, y) points), and returns the union"""
clipper = pyclipper.Pyclipper() # pylint: disable=c-extension-no-member
scaled_first = pyclipper.scale_to_clipper(first, SCALING_FACTOR)
scaled_second = pyclipper.scale_to_clipper(second, SCALING_FACTOR)
clipper.AddPaths(scaled_first, pyclipper.PT_SUBJECT)
clipper.AddPaths(scaled_second, pyclipper.PT_CLIP)
scaled_union = clipper.Execute(pyclipper.CT_UNION)
union = pyclipper.scale_from_clipper(
scaled_union, SCALING_FACTOR)
return union
def get_xor(first, second):
"""Takes two list of loops(list of(x, y) points), and returns the exclusive-or"""
clipper = pyclipper.Pyclipper() # pylint: disable=c-extension-no-member
scaled_first = pyclipper.scale_to_clipper(first, SCALING_FACTOR)
scaled_second = pyclipper.scale_to_clipper(second, SCALING_FACTOR)
clipper.AddPaths(scaled_first, pyclipper.PT_SUBJECT)
clipper.AddPaths(scaled_second, pyclipper.PT_CLIP)
scaled_xor = clipper.Execute(pyclipper.CT_XOR)
xor = pyclipper.scale_from_clipper(
scaled_xor, SCALING_FACTOR)
return xor
def get_offset_loop(shape, offset_size):
"""takes a list of loops (list of(x, y) points), and returns loops offset by a given size"""
offsetter = pyclipper.PyclipperOffset()
scaled_shape = pyclipper.scale_to_clipper(shape, SCALING_FACTOR)
scaled_offset_size = offset_size * SCALING_FACTOR
offsetter.AddPaths(scaled_shape, pyclipper.JT_ROUND, pyclipper.PT_SUBJECT)
scaled_offset = offsetter.Execute(scaled_offset_size)
offset = pyclipper.scale_from_clipper(scaled_offset, SCALING_FACTOR)
return offset
def point_inside_loop(point, loop):
"""tests to see if a point is inside (1), on(-1), or outside (0) of a loop"""
scaled_loop = pyclipper.scale_to_clipper(loop, SCALING_FACTOR)
scaled_point = [int(point[0] * SCALING_FACTOR),
int(point[1] * SCALING_FACTOR)]
is_point_inside = pyclipper.PointInPolygon(scaled_point, scaled_loop)
return is_point_inside
def point_on_loops(point, loops):
"""True or False based upon if a point is on any loop in a list of loops."""
for loop in loops:
if point_inside_loop(point, loop) == -1:
return True
return False