Working polylines demo
This commit is contained in:
60
main.py
60
main.py
@@ -286,9 +286,9 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete",
|
|||||||
# p = Polyline((Point2D(-1225, 468), Point2D(-1138, 481),
|
# p = Polyline((Point2D(-1225, 468), Point2D(-1138, 481),
|
||||||
# Point2D(-1188, 451), Point2D(-1176, 409), Point2D(-1179, 399)))
|
# Point2D(-1188, 451), Point2D(-1176, 409), Point2D(-1179, 399)))
|
||||||
|
|
||||||
w = 250
|
w = 200
|
||||||
|
|
||||||
n_points = 5
|
n_points = 20
|
||||||
min_val, max_val = -w, w
|
min_val, max_val = -w, w
|
||||||
|
|
||||||
random_points = [Point2D(random.randint(min_val, max_val), random.randint(
|
random_points = [Point2D(random.randint(min_val, max_val), random.randint(
|
||||||
@@ -298,6 +298,8 @@ random_points = [Point2D(random.randint(min_val, max_val), random.randint(
|
|||||||
# random_points = (Point2D(-75, -75), Point2D(0, -75), Point2D(75, 75),
|
# random_points = (Point2D(-75, -75), Point2D(0, -75), Point2D(75, 75),
|
||||||
# Point2D(75, -50), Point2D(-50, 50), Point2D(0, 0))
|
# Point2D(75, -50), Point2D(-50, 50), Point2D(0, 0))
|
||||||
|
|
||||||
|
random_points = random_points[0].optimized_path(random_points)
|
||||||
|
|
||||||
p = Polyline(random_points)
|
p = Polyline(random_points)
|
||||||
|
|
||||||
# Point2D(-1156, 378), Point2D(-1220, 359), Point2D(-1265, 290)
|
# Point2D(-1156, 378), Point2D(-1220, 359), Point2D(-1265, 290)
|
||||||
@@ -307,14 +309,15 @@ radius = p.get_radii()
|
|||||||
center = p.get_centers()
|
center = p.get_centers()
|
||||||
|
|
||||||
y = 200
|
y = 200
|
||||||
|
ww = 15
|
||||||
ww = 40
|
|
||||||
|
|
||||||
width, height = 2*w, 2*w
|
width, height = 2*w, 2*w
|
||||||
image = Image.new('RGB', (width, height), 'white')
|
image = Image.new('RGB', (width, height), 'black')
|
||||||
|
|
||||||
draw = ImageDraw.Draw(image)
|
draw = ImageDraw.Draw(image)
|
||||||
|
|
||||||
|
print(p.output_points)
|
||||||
|
|
||||||
for i in range(len(p.output_points)-1):
|
for i in range(len(p.output_points)-1):
|
||||||
if p.output_points[i] != None:
|
if p.output_points[i] != None:
|
||||||
s = Segment2D(Point2D(p.output_points[i].x, p.output_points[i].y), Point2D(
|
s = Segment2D(Point2D(p.output_points[i].x, p.output_points[i].y), Point2D(
|
||||||
@@ -325,18 +328,59 @@ for i in range(len(p.output_points)-1):
|
|||||||
# editor.placeBlock(
|
# editor.placeBlock(
|
||||||
# s.coordinates[j].coordinate, Block("cyan_concrete"))
|
# s.coordinates[j].coordinate, Block("cyan_concrete"))
|
||||||
draw.point((s.points_thick[j].x+w,
|
draw.point((s.points_thick[j].x+w,
|
||||||
w-s.points_thick[j].y), fill='red')
|
w-s.points_thick[j].y), fill='grey')
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(2, len(p.get_arcs_intersections())-2):
|
||||||
|
|
||||||
|
s = Segment2D(Point2D(p.acrs_intersections[i][0].x, p.acrs_intersections[i][0].y), Point2D(
|
||||||
|
p.acrs_intersections[i-1][-1].x, p.acrs_intersections[i-1][-1].y))
|
||||||
|
s.segment_thick(ww, LINE_THICKNESS_MODE.MIDDLE)
|
||||||
|
|
||||||
|
for j in range(len(s.points_thick)-1):
|
||||||
|
# editor.placeBlock(
|
||||||
|
# s.coordinates[j].coordinate, Block("cyan_concrete"))
|
||||||
|
draw.point((s.points_thick[j].x+w,
|
||||||
|
w-s.points_thick[j].y), fill='white')
|
||||||
|
draw.point((p.acrs_intersections[i][0].x+w,
|
||||||
|
w-p.acrs_intersections[i][0].y), fill='blue')
|
||||||
|
draw.point((p.acrs_intersections[i][-1].x+w,
|
||||||
|
w-p.acrs_intersections[i][-1].y), fill='red')
|
||||||
|
|
||||||
|
|
||||||
for i in range(len(center)):
|
for i in range(len(center)):
|
||||||
if center[i]:
|
if center[i]:
|
||||||
circle = Circle(center[i])
|
circle = Circle(center[i])
|
||||||
circle.circle_thick(radius[i]-ww/2+1, radius[i]+ww/2+1)
|
circle.circle_thick(round(radius[i]-ww/2), round(radius[i]+ww/2))
|
||||||
for j in range(len(circle.points_thick)-1):
|
for j in range(len(circle.points_thick)-1):
|
||||||
|
if circle.points_thick[j].is_in_triangle(p.acrs_intersections[i][0], p.acrs_intersections[i][1], p.acrs_intersections[i][2]):
|
||||||
# editor.placeBlock(
|
# editor.placeBlock(
|
||||||
# (circle.coordinates[j].x, y, circle.coordinates[j].y), Block("white_concrete"))
|
# (circle.coordinates[j].x, y, circle.coordinates[j].y), Block("white_concrete"))
|
||||||
draw.point((circle.points_thick[j].x+w,
|
draw.point((circle.points_thick[j].x+w,
|
||||||
w-circle.points_thick[j].y), fill='black')
|
w-circle.points_thick[j].y), fill='white')
|
||||||
|
circle.circle(radius[i])
|
||||||
|
for j in range(len(circle.points)-1):
|
||||||
|
if circle.points[j].is_in_triangle(p.acrs_intersections[i][0], p.acrs_intersections[i][1], p.acrs_intersections[i][2]):
|
||||||
|
# editor.placeBlock(
|
||||||
|
# (circle.coordinates[j].x, y, circle.coordinates[j].y), Block("white_concrete"))
|
||||||
|
draw.point((circle.points[j].x+w,
|
||||||
|
w-circle.points[j].y), fill='purple')
|
||||||
|
|
||||||
|
s1 = Segment2D(Point2D(p.acrs_intersections[1][0].x, p.acrs_intersections[1][0].y), Point2D(
|
||||||
|
p.output_points[0].x, p.output_points[0].y))
|
||||||
|
s1.segment_thick(ww, LINE_THICKNESS_MODE.MIDDLE)
|
||||||
|
|
||||||
|
for j in range(len(s1.points_thick)-1):
|
||||||
|
draw.point((s1.points_thick[j].x+w,
|
||||||
|
w-s1.points_thick[j].y), fill='white')
|
||||||
|
|
||||||
|
s1 = Segment2D(Point2D(p.acrs_intersections[-2][2].x, p.acrs_intersections[-2][2].y), Point2D(
|
||||||
|
p.output_points[-1].x, p.output_points[-1].y))
|
||||||
|
s1.segment_thick(ww, LINE_THICKNESS_MODE.MIDDLE)
|
||||||
|
|
||||||
|
for j in range(len(s1.points_thick)-1):
|
||||||
|
draw.point((s1.points_thick[j].x+w,
|
||||||
|
w-s1.points_thick[j].y), fill='white')
|
||||||
|
|
||||||
image.save('output_image.png')
|
image.save('output_image.png')
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Circle:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Circle(center: {self.center}, radius: {self.radius}, spaced_radius: {self.spaced_radius}, inner: {self.inner}, outer: {self.outer})"
|
return f"Circle(center: {self.center}, radius: {self.radius}, spaced_radius: {self.spaced_radius}, inner: {self.inner}, outer: {self.outer})"
|
||||||
|
|
||||||
def cirlce(self, radius: int) -> List[Point2D]:
|
def circle(self, radius: int) -> List[Point2D]:
|
||||||
self.radius = radius
|
self.radius = radius
|
||||||
center = self.center.copy()
|
center = self.center.copy()
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ class Polyline:
|
|||||||
|
|
||||||
>>> Polyline((Point2D(0, 0), Point2D(0, 10), Point2D(50, 10), Point2D(20, 20)))
|
>>> Polyline((Point2D(0, 0), Point2D(0, 10), Point2D(50, 10), Point2D(20, 20)))
|
||||||
"""
|
"""
|
||||||
self.points = Point2D.to_vectors(self._remove_collinear_points(points))
|
self.points_array = Point2D.to_vectors(
|
||||||
self.length_polyline = len(points)
|
self._remove_collinear_points(points))
|
||||||
|
self.length_polyline = len(self.points_array)
|
||||||
|
|
||||||
if self.length_polyline < 4:
|
if self.length_polyline < 4:
|
||||||
raise ValueError("The list must contain at least 4 elements.")
|
raise ValueError("The list must contain at least 4 elements.")
|
||||||
@@ -29,11 +30,12 @@ class Polyline:
|
|||||||
self.unit_vectors = [None] * self.length_polyline # n
|
self.unit_vectors = [None] * self.length_polyline # n
|
||||||
self.tangente = [0] * self.length_polyline # f
|
self.tangente = [0] * self.length_polyline # f
|
||||||
|
|
||||||
self.alpha_radii = [None] * self.length_polyline # alpha
|
# alpha, maximum radius factor
|
||||||
|
self.alpha_radii = [None] * self.length_polyline
|
||||||
|
|
||||||
self.radii = [None] * self.length_polyline # r
|
self.radii = [None] * self.length_polyline # r
|
||||||
self.centers = [None] * self.length_polyline # c
|
self.centers = [None] * self.length_polyline # c
|
||||||
self.connections = [None] * self.length_polyline
|
self.acrs_intersections = [None] * self.length_polyline
|
||||||
|
|
||||||
self._compute_requirements()
|
self._compute_requirements()
|
||||||
self._compute_alpha_radii()
|
self._compute_alpha_radii()
|
||||||
@@ -58,19 +60,20 @@ class Polyline:
|
|||||||
bisector = (self.unit_vectors[i] - self.unit_vectors[i-1]) / (
|
bisector = (self.unit_vectors[i] - self.unit_vectors[i-1]) / (
|
||||||
np.linalg.norm(self.unit_vectors[i] - self.unit_vectors[i-1]))
|
np.linalg.norm(self.unit_vectors[i] - self.unit_vectors[i-1]))
|
||||||
|
|
||||||
array = self.points[i] + sqrt((self.radii[i]
|
array = self.points_array[i] + sqrt((self.radii[i]
|
||||||
** 2) + (self.alpha_radii[i] ** 2)) * bisector
|
** 2) + (self.alpha_radii[i] ** 2)) * bisector
|
||||||
self.centers[i] = Point2D(array[0], array[1]).round()
|
self.centers[i] = Point2D(array[0], array[1]).round()
|
||||||
return self.centers
|
return self.centers
|
||||||
|
|
||||||
def get_arcs(self):
|
def get_arcs_intersections(self):
|
||||||
for i in range(1, self.length_polyline-1):
|
for i in range(1, self.length_polyline-1):
|
||||||
point_1 = self.points[i] - \
|
point_1 = self.points_array[i] - \
|
||||||
self.alpha_radii[i] * self.unit_vectors[i-1]
|
self.alpha_radii[i] * self.unit_vectors[i-1]
|
||||||
point_2 = self.points[i] + \
|
point_2 = self.points_array[i] + \
|
||||||
self.alpha_radii[i] * self.unit_vectors[i]
|
self.alpha_radii[i] * self.unit_vectors[i]
|
||||||
self.connections[i] = (point_1, point_2)
|
self.acrs_intersections[i] = Point2D(
|
||||||
return self.connections
|
point_1[0], point_1[1]).round(), Point2D(self.points_array[i][0], self.points_array[i][1]), Point2D(point_2[0], point_2[1]).round()
|
||||||
|
return self.acrs_intersections
|
||||||
|
|
||||||
def _alpha_assign(self, start_index: int, end_index: int):
|
def _alpha_assign(self, start_index: int, end_index: int):
|
||||||
"""
|
"""
|
||||||
@@ -109,9 +112,8 @@ class Polyline:
|
|||||||
alpha_low, alpha_high = alpha_a, self.alpha_radii[end_index]
|
alpha_low, alpha_high = alpha_a, self.alpha_radii[end_index]
|
||||||
|
|
||||||
# Assign alphas at ends of selected segment
|
# Assign alphas at ends of selected segment
|
||||||
self.alpha_radii[minimum_index] = alpha_low/1.5
|
self.alpha_radii[minimum_index] = alpha_low
|
||||||
self.alpha_radii[minimum_index+1] = alpha_high/1.5
|
self.alpha_radii[minimum_index+1] = alpha_high
|
||||||
|
|
||||||
# Recur on lower segments
|
# Recur on lower segments
|
||||||
self._alpha_assign(start_index, minimum_index)
|
self._alpha_assign(start_index, minimum_index)
|
||||||
# Recur on higher segments
|
# Recur on higher segments
|
||||||
@@ -130,7 +132,7 @@ class Polyline:
|
|||||||
def _compute_requirements(self):
|
def _compute_requirements(self):
|
||||||
# Between two points, there is only one segment
|
# Between two points, there is only one segment
|
||||||
for j in range(self.length_polyline-1):
|
for j in range(self.length_polyline-1):
|
||||||
self.vectors[j] = self.points[j+1] - self.points[j]
|
self.vectors[j] = self.points_array[j+1] - self.points_array[j]
|
||||||
self.lengths[j] = np.linalg.norm(self.vectors[j])
|
self.lengths[j] = np.linalg.norm(self.vectors[j])
|
||||||
self.unit_vectors[j] = self.vectors[j]/self.lengths[j]
|
self.unit_vectors[j] = self.vectors[j]/self.lengths[j]
|
||||||
|
|
||||||
|
|||||||
BIN
output_image.png
BIN
output_image.png
Binary file not shown.
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 5.6 KiB |
Reference in New Issue
Block a user