Fix thick bresenham

This commit is contained in:
2024-06-13 00:01:11 +02:00
parent 48db1202aa
commit 143a574235
4 changed files with 40 additions and 28 deletions

44
main.py
View File

@@ -1,4 +1,5 @@
from networks.geometry.Enums import LINE_OVERLAP, LINE_THICKNESS_MODE
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from networks.geometry.Point3D import Point3D from networks.geometry.Point3D import Point3D
@@ -286,14 +287,18 @@ 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 = 1000 w = 250
n_points = 10 n_points = 5
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(
min_val, max_val)) for _ in range(n_points)] min_val, max_val)) for _ in range(n_points)]
# random_points = (Point2D(-75, -75), Point2D(0, -75), Point2D(75, 75),
# Point2D(75, -50), Point2D(-50, 50), Point2D(0, 0))
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)
@@ -301,37 +306,40 @@ p = Polyline(random_points)
radius = p.get_radii() radius = p.get_radii()
center = p.get_centers() center = p.get_centers()
print(radius) print(radius)
print(center) print(center)
print(p.lengths) print(p.lengths)
y = 160 y = 200
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), 'white')
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
for i in range(len(center)):
if center[i]:
circle = Circle(center[i], radius[i], radius[i]+1)
for j in range(len(circle.coordinates)-1):
editor.placeBlock(
(circle.coordinates[j].x, y, circle.coordinates[j].y), Block("white_concrete"))
draw.point((circle.coordinates[j].x+w,
w-circle.coordinates[j].y), fill='black')
for i in range(len(p.coordinates)-1): for i in range(len(p.coordinates)-1):
if p.coordinates[i] != None: if p.coordinates[i] != None:
s = Segment3D(Point3D(p.coordinates[i].x, y, p.coordinates[i].y), Point3D( s = Segment2D(Point2D(p.coordinates[i].x, p.coordinates[i].y), Point2D(
p.coordinates[i+1].x, y, p.coordinates[i+1].y)) p.coordinates[i+1].x, p.coordinates[i+1].y))
s.compute_thick_segment(ww, LINE_THICKNESS_MODE.MIDDLE)
print(s.coordinates)
for j in range(len(s.coordinates)-1): for j in range(len(s.coordinates)-1):
editor.placeBlock( # editor.placeBlock(
s.coordinates[j].coordinate, Block("cyan_concrete")) # s.coordinates[j].coordinate, Block("cyan_concrete"))
draw.point((s.coordinates[j].x+w, draw.point((s.coordinates[j].x+w,
w-s.coordinates[j].z), fill='red') w-s.coordinates[j].y), fill='red')
for i in range(len(center)):
if center[i]:
circle = Circle(center[i], radius[i]-ww/2+1, radius[i]+ww/2+1)
for j in range(len(circle.coordinates)-1):
# editor.placeBlock(
# (circle.coordinates[j].x, y, circle.coordinates[j].y), Block("white_concrete"))
draw.point((circle.coordinates[j].x+w,
w-circle.coordinates[j].y), fill='black')
image.save('output_image.png') image.save('output_image.png')

View File

@@ -98,8 +98,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 self.alpha_radii[minimum_index] = alpha_low/1.5
self.alpha_radii[minimum_index+1] = alpha_high self.alpha_radii[minimum_index+1] = alpha_high/1.5
# Recur on lower segments # Recur on lower segments
self._alpha_assign(start_index, minimum_index) self._alpha_assign(start_index, minimum_index)

View File

@@ -27,6 +27,7 @@ class Segment2D:
>>> Segment2D(Point2D(0, 0), Point2D(10, 15)) >>> Segment2D(Point2D(0, 0), Point2D(10, 15))
""" """
start = start.copy() start = start.copy()
end = end.copy() end = end.copy()
@@ -62,10 +63,10 @@ class Segment2D:
start.y += step_y start.y += step_y
if (overlap == LINE_OVERLAP.MINOR): if (overlap == LINE_OVERLAP.MINOR):
self.coordinates.append( self.coordinates.append(
Point2D(start.x - step_x, start.y)) Point2D(start.copy().x - step_x, start.copy().y))
error -= delta_2x error -= delta_2x
error += delta_2y error += delta_2y
self.coordinates.append(start) self.coordinates.append(start.copy())
else: else:
error = delta_2x - delta_y error = delta_2x - delta_y
while (start.y != end.y): while (start.y != end.y):
@@ -77,12 +78,12 @@ class Segment2D:
start.x += step_x start.x += step_x
if (overlap == LINE_OVERLAP.MINOR): if (overlap == LINE_OVERLAP.MINOR):
self.coordinates.append( self.coordinates.append(
Point2D(start.x, start.y - step_y)) Point2D(start.copy().x, start.copy().y - step_y))
error -= delta_2y error -= delta_2y
error += delta_2x error += delta_2x
self.coordinates.append(start.copy()) self.coordinates.append(start.copy())
def compute_thick_segment(self, start: Point2D, end: Point2D, thickness: int, thickness_mode: LINE_THICKNESS_MODE): def compute_thick_segment(self, thickness: int, thickness_mode: LINE_THICKNESS_MODE):
"""Bresenham with thickness. """Bresenham with thickness.
From https://github.com/ArminJo/Arduino-BlueDisplay/blob/master/src/LocalGUI/ThickLine.hpp From https://github.com/ArminJo/Arduino-BlueDisplay/blob/master/src/LocalGUI/ThickLine.hpp
@@ -96,11 +97,14 @@ class Segment2D:
>>> self.compute_thick_segment(self.start, self.end, self.thickness, self.thickness_mode) >>> self.compute_thick_segment(self.start, self.end, self.thickness, self.thickness_mode)
""" """
start = self.start.copy()
end = self.end.copy()
delta_y = end.x - start.x delta_y = end.x - start.x
delta_x = end.y - start.y delta_x = end.y - start.y
swap = True swap = True
if delta_x < 0: if (delta_x < 0):
delta_x = -delta_x delta_x = -delta_x
step_x = -1 step_x = -1
swap = not swap swap = not swap
@@ -156,7 +160,7 @@ class Segment2D:
overlap = LINE_OVERLAP.MAJOR overlap = LINE_OVERLAP.MAJOR
error += delta_2y error += delta_2y
self.compute_segmen_overlap(start, end, overlap) self.compute_segment_overlap(start, end, overlap)
else: else:
if swap: if swap:
@@ -176,7 +180,7 @@ class Segment2D:
error -= delta_2y error -= delta_2y
error += delta_2x error += delta_2x
self.compute_segmen_overlap(start, end, LINE_OVERLAP.NONE) self.compute_segment_overlap(start, end, LINE_OVERLAP.NONE)
error = delta_2x - delta_y error = delta_2x - delta_y
for i in range(thickness, 1, -1): for i in range(thickness, 1, -1):
@@ -190,7 +194,7 @@ class Segment2D:
overlap = LINE_OVERLAP.MAJOR overlap = LINE_OVERLAP.MAJOR
error += delta_2x error += delta_2x
self.compute_segmen_overlap(start, end, overlap) self.compute_segment_overlap(start, end, overlap)
def perpendicular(self, distance: int) -> List[Point2D]: def perpendicular(self, distance: int) -> List[Point2D]:
"""Compute perpendicular points from both side of the segment placed at start level. """Compute perpendicular points from both side of the segment placed at start level.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB