Fix Segments

This commit is contained in:
2024-06-11 03:45:25 +02:00
parent c879f209d8
commit 9433503ddd
3 changed files with 46 additions and 24 deletions

View File

@@ -1,3 +1,6 @@
from networks.geometry.Point3D import Point3D
from networks.geometry.Segment3D import Segment3D
from networks.geometry.Segment2D import Segment2D
from networks.geometry.Circle import Circle from networks.geometry.Circle import Circle
from networks.geometry.Polyline import Polyline from networks.geometry.Polyline import Polyline
from networks.geometry.Point2D import Point2D from networks.geometry.Point2D import Point2D
@@ -261,3 +264,7 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete",
# # polyline._alpha_assign(1, polyline.length_polyline-1) # # polyline._alpha_assign(1, polyline.length_polyline-1)
# print(polyline.alpha_radii) # print(polyline.alpha_radii)
s = Segment2D(Point2D(0, 0), Point2D(10, 15), 1)
print(s)

View File

@@ -4,20 +4,28 @@ from networks.geometry.Point2D import Point2D
class Segment2D: class Segment2D:
def __init__(start: Type[Point2D], end: Type[Point2D]): def __init__(self, start: Point2D, end: Point2D, thickness: int, thickness_mode: LINE_THICKNESS_MODE = LINE_THICKNESS_MODE.MIDDLE):
self.start = start self.start = start
self.end = end self.end = end
self.coordinates = [] self.coordinates = []
self.thickness = thickness
self.thickness_mode = thickness_mode
def compute_segment_overlap(start: Type[Point2D], end: Type[Point2D], overlap: Type[LINE_OVERLAP]): self.compute_thick_segment(
self.start, self.end, self.thickness, self.thickness_mode)
def __repr__(self):
return str(self.coordinates)
def compute_segment_overlap(self, start: Point2D, end: Point2D, overlap: LINE_OVERLAP):
"""Modified Bresenham draw (line) with optional overlap. """Modified Bresenham draw (line) with optional overlap.
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
Args: Args:
start (Type[Point2D]): Start point of the segment. start (Point2D): Start point of the segment.
end (Type[Point2D]): End point of the segment. end (Point2D): End point of the segment.
overlap (Type[LINE_OVERLAP]): Overlap draws additional pixel when changing minor direction. For standard bresenham overlap, choose LINE_OVERLAP_NONE. Can also be LINE_OVERLAP_MAJOR or LINE_OVERLAP_MINOR. overlap (LINE_OVERLAP): Overlap draws additional pixel when changing minor direction. For standard bresenham overlap, choose LINE_OVERLAP_NONE. Can also be LINE_OVERLAP_MAJOR or LINE_OVERLAP_MINOR.
""" """
start = start.copy() start = start.copy()
end = end.copy() end = end.copy()
@@ -41,7 +49,7 @@ class Segment2D:
delta_2x = 2*delta_x delta_2x = 2*delta_x
delta_2y = 2*delta_y delta_2y = 2*delta_y
self.coordinates.append(start) self.coordinates.append(start.copy())
if (delta_x > delta_y): if (delta_x > delta_y):
error = delta_2y - delta_x error = delta_2y - delta_x
@@ -49,7 +57,7 @@ class Segment2D:
start.x += step_x start.x += step_x
if (error >= 0): if (error >= 0):
if (overlap == LINE_OVERLAP.MAJOR): if (overlap == LINE_OVERLAP.MAJOR):
self.coordinates.append(start) self.coordinates.append(start.copy())
start.y += step_y start.y += step_y
if (overlap == LINE_OVERLAP.MINOR): if (overlap == LINE_OVERLAP.MINOR):
@@ -64,7 +72,7 @@ class Segment2D:
start.y += step_y start.y += step_y
if (error >= 0): if (error >= 0):
if (overlap == LINE_OVERLAP.MAJOR): if (overlap == LINE_OVERLAP.MAJOR):
self.coordinates.append(start) self.coordinates.append(start.copy())
start.x += step_x start.x += step_x
if (overlap == LINE_OVERLAP.MINOR): if (overlap == LINE_OVERLAP.MINOR):
@@ -72,19 +80,19 @@ class Segment2D:
Point2D(start.x, start.y - step_y)) Point2D(start.x, start.y - step_y))
error -= delta_2y error -= delta_2y
error += delta_2x error += delta_2x
self.coordinates.append(start) self.coordinates.append(start.copy())
def compute_thick_segment(start: Type[Point2D], end: Type[Point2D], thickness: int, thickness_mode: Type[LINE_THICKNESS_MODE]): def compute_thick_segment(self, start: Point2D, end: Point2D, 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
Probably inspired from Murphy's Modified Bresenham algorithm : http://zoo.co.uk/murphy/thickline/index.html Probably inspired from Murphy's Modified Bresenham algorithm : http://zoo.co.uk/murphy/thickline/index.html
Args: Args:
start (Type[Point2D]): Start point of the segment. start (Point2D): Start point of the segment.
end (Type[Point2D]): End point of the segment. end (Point2D): End point of the segment.
thickness (int): Total width of the surface. Placement relative to the original segment depends on thickness_mode. thickness (int): Total width of the surface. Placement relative to the original segment depends on thickness_mode.
thickness_mode (Type[LINE_THICKNESS_MODE]): Can be one of LINE_THICKNESS_MIDDLE, LINE_THICKNESS_DRAW_CLOCKWISE, LINE_THICKNESS_DRAW_COUNTERCLOCKWISE. thickness_mode (LINE_THICKNESS_MODE): Can be one of LINE_THICKNESS_MIDDLE, LINE_THICKNESS_DRAW_CLOCKWISE, LINE_THICKNESS_DRAW_COUNTERCLOCKWISE.
""" """
delta_y = end.x - start.x delta_y = end.x - start.x
delta_x = end.y - start.y delta_x = end.y - start.y
@@ -108,9 +116,9 @@ class Segment2D:
delta_2y = 2 * delta_y delta_2y = 2 * delta_y
draw_start_adjust_count = int(thickness / 2) draw_start_adjust_count = int(thickness / 2)
if (thickness_mode == LineThicknessMode.DRAW_COUNTERCLOCKWISE): if (thickness_mode == LINE_THICKNESS_MODE.DRAW_COUNTERCLOCKWISE):
draw_start_adjust_count = thickness - 1 draw_start_adjust_count = thickness - 1
elif (thickness_mode == LineThicknessMode.DRAW_CLOCKWISE): elif (thickness_mode == LINE_THICKNESS_MODE.DRAW_CLOCKWISE):
draw_start_adjust_count = 0 draw_start_adjust_count = 0
if (delta_x >= delta_y): if (delta_x >= delta_y):
@@ -132,7 +140,7 @@ class Segment2D:
error -= delta_2x error -= delta_2x
error += delta_2x error += delta_2x
draw_line_overlap(start, end, LINE_OVERLAP.NONE) self.compute_segment_overlap(start, end, LINE_OVERLAP.NONE)
error = delta_2x - delta_x error = delta_2x - delta_x
for i in range(thickness, 1, -1): for i in range(thickness, 1, -1):
@@ -146,7 +154,7 @@ class Segment2D:
overlap = LINE_OVERLAP.MAJOR overlap = LINE_OVERLAP.MAJOR
error += delta_2y error += delta_2y
draw_line_overlap(start, end, overlap) self.compute_segmen_overlap(start, end, overlap)
else: else:
if swap: if swap:
@@ -166,7 +174,7 @@ class Segment2D:
error -= delta_2y error -= delta_2y
error += delta_2x error += delta_2x
draw_line_overlap(start, end, LINE_OVERLAP.NONE) self.compute_segmen_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):
@@ -180,4 +188,4 @@ class Segment2D:
overlap = LINE_OVERLAP.MAJOR overlap = LINE_OVERLAP.MAJOR
error += delta_2x error += delta_2x
draw_line_overlap(start, end, overlap) self.compute_segmen_overlap(start, end, overlap)

View File

@@ -1,23 +1,30 @@
from typing import Type
from networks.geometry.Enums import LINE_OVERLAP from networks.geometry.Enums import LINE_OVERLAP
from networks.geometry.Point3D import Point3D from networks.geometry.Point3D import Point3D
class Segment3D: class Segment3D:
def __init__(start: Type[Point3D], end: Type[Point3D]): def __init__(self, start: Point3D, end: Point3D, overlap: bool = True):
self.start = start self.start = start
self.end = end self.end = end
self.coordinates = [] self.coordinates = []
self.overlap = overlap
def compute_segment(start: Type[Point3D], end: Type[Point3D], overlap=True): self.compute_segment(self.start, self.end, self.overlap)
def __repr__(self):
return str(self.coordinates)
def compute_segment(self, start: Point3D, end: Point3D, overlap: bool = True):
"""Calculate a segment between two points in 3D space. 3d Bresenham algorithm. """Calculate a segment between two points in 3D space. 3d Bresenham algorithm.
From: https://www.geeksforgeeks.org/bresenhams-algorithm-for-3-d-line-drawing/ From: https://www.geeksforgeeks.org/bresenhams-algorithm-for-3-d-line-drawing/
Args: Args:
start (Type[Point3D]): First coordinates. start (Point3D): First coordinates.
end (Type[Point3D]): Second coordinates. end (Point3D): Second coordinates.
overlap (bool, optional): If true, remove unnecessary coordinates connecting to other coordinates side by side, leaving only a diagonal connection. Defaults to True. overlap (bool, optional): If true, remove unnecessary coordinates connecting to other coordinates side by side, leaving only a diagonal connection. Defaults to True.
>>> Segment3D(Point3D(0, 0, 0), Point3D(10, 10, 15))
""" """
self.coordinates.append(start) self.coordinates.append(start)
dx = abs(end.x - start.x) dx = abs(end.x - start.x)