Add 3d objects
This commit is contained in:
17
networks/geometry/Point3D.py
Normal file
17
networks/geometry/Point3D.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from typing import Type
|
||||
|
||||
|
||||
class Point3D:
|
||||
def __init__(self, x: int, y: int, z: int):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
|
||||
def copy(self):
|
||||
return Point3D(self.x, self.y, self.z)
|
||||
|
||||
def coordinates(self):
|
||||
return (self.x, self.y, self.z)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Point2D(x: {self.x}, y: {self.y}, z: {self.z})"
|
||||
@@ -9,7 +9,7 @@ class Segment2D:
|
||||
self.end = end
|
||||
self.coordinates = []
|
||||
|
||||
def draw_line_overlap(start: Type[Point2D], end: Type[Point2D], overlap: Type[LINE_OVERLAP]):
|
||||
def compute_segment_overlap(start: Type[Point2D], end: Type[Point2D], overlap: Type[LINE_OVERLAP]):
|
||||
"""Modified Bresenham draw (line) with optional overlap.
|
||||
|
||||
From https://github.com/ArminJo/Arduino-BlueDisplay/blob/master/src/LocalGUI/ThickLine.hpp
|
||||
@@ -74,7 +74,7 @@ class Segment2D:
|
||||
error += delta_2x
|
||||
self.coordinates.append(start)
|
||||
|
||||
def draw_thick_line(start: Type[Point2D], end: Type[Point2D], thickness: int, thickness_mode: Type[LINE_THICKNESS_MODE]):
|
||||
def compute_thick_segment(start: Type[Point2D], end: Type[Point2D], thickness: int, thickness_mode: Type[LINE_THICKNESS_MODE]):
|
||||
"""Bresenham with thickness.
|
||||
|
||||
From https://github.com/ArminJo/Arduino-BlueDisplay/blob/master/src/LocalGUI/ThickLine.hpp
|
||||
|
||||
@@ -8,3 +8,96 @@ class Segment3D:
|
||||
self.start = start
|
||||
self.end = end
|
||||
self.coordinates = []
|
||||
|
||||
def compute_segment(start: Type[Point3D], end: Type[Point3D], overlap=True):
|
||||
"""Calculate a segment between two points in 3D space. 3d Bresenham algorithm.
|
||||
|
||||
From: https://www.geeksforgeeks.org/bresenhams-algorithm-for-3-d-line-drawing/
|
||||
|
||||
Args:
|
||||
start (Type[Point3D]): First coordinates.
|
||||
end (Type[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.
|
||||
"""
|
||||
self.coordinates.append(start)
|
||||
dx = abs(end.x - start.x)
|
||||
dy = abs(end.y - start.y)
|
||||
dz = abs(end.z - start.z)
|
||||
if end.x > start.x:
|
||||
xs = 1
|
||||
else:
|
||||
xs = -1
|
||||
if end.y > start.y:
|
||||
ys = 1
|
||||
else:
|
||||
ys = -1
|
||||
if end.z > start.z:
|
||||
zs = 1
|
||||
else:
|
||||
zs = -1
|
||||
|
||||
# Driving axis is X-axis
|
||||
if dx >= dy and dx >= dz:
|
||||
p1 = 2 * dy - dx
|
||||
p2 = 2 * dz - dx
|
||||
while start.x != end.x:
|
||||
start.x += xs
|
||||
self.coordinates.append(start)
|
||||
if p1 >= 0:
|
||||
start.y += ys
|
||||
if not overlap:
|
||||
if self.coordinates[-1].y != start.y:
|
||||
self.coordinates.append(start)
|
||||
p1 -= 2 * dx
|
||||
if p2 >= 0:
|
||||
start.z += zs
|
||||
if not overlap:
|
||||
if self.coordinates[-1].z != start.z:
|
||||
self.coordinates.append(start)
|
||||
p2 -= 2 * dx
|
||||
p1 += 2 * dy
|
||||
p2 += 2 * dz
|
||||
|
||||
# Driving axis is Y-axis
|
||||
elif dy >= dx and dy >= dz:
|
||||
p1 = 2 * dx - dy
|
||||
p2 = 2 * dz - dy
|
||||
while start.y != end.y:
|
||||
start.y += ys
|
||||
self.coordinates.append(start)
|
||||
if p1 >= 0:
|
||||
start.x += xs
|
||||
if not overlap:
|
||||
if self.coordinates[-1].x != start.x:
|
||||
self.coordinates.append(start)
|
||||
p1 -= 2 * dy
|
||||
if p2 >= 0:
|
||||
start.z += zs
|
||||
if not overlap:
|
||||
if self.coordinates[-1].z != start.z:
|
||||
self.coordinates.append(start)
|
||||
p2 -= 2 * dy
|
||||
p1 += 2 * dx
|
||||
p2 += 2 * dz
|
||||
|
||||
# Driving axis is Z-axis
|
||||
else:
|
||||
p1 = 2 * dy - dz
|
||||
p2 = 2 * dx - dz
|
||||
while start.z != end.z:
|
||||
start.z += zs
|
||||
self.coordinates.append(start)
|
||||
if p1 >= 0:
|
||||
start.y += ys
|
||||
if not overlap:
|
||||
if self.coordinates[-1].y != start.y:
|
||||
self.coordinates.append(start)
|
||||
p1 -= 2 * dz
|
||||
if p2 >= 0:
|
||||
start.x += xs
|
||||
if not overlap:
|
||||
if self.coordinates[-1].x != start.x:
|
||||
self.coordinates.append(start)
|
||||
p2 -= 2 * dz
|
||||
p1 += 2 * dy
|
||||
p2 += 2 * dx
|
||||
|
||||
322
networks/test.py
322
networks/test.py
@@ -1,322 +0,0 @@
|
||||
from gdpc import Editor, Block, geometry
|
||||
from enum import Enum
|
||||
import random
|
||||
|
||||
|
||||
def circle(xm, ym, r, pixel_perfect=True):
|
||||
editor = Editor(buffering=True)
|
||||
block = random.choices(("white_concrete", "red_concrete", "blue_concrete", "green_concrete",
|
||||
"yellow_concrete", "black_concrete", "purple_concrete", "pink_concrete"))[0]
|
||||
x = -r
|
||||
y = 0
|
||||
err = 2-2*r
|
||||
while (True):
|
||||
editor.placeBlock((xm-x, 141, ym+y),
|
||||
Block(block))
|
||||
editor.placeBlock((xm-y, 141, ym-x),
|
||||
Block(block))
|
||||
editor.placeBlock((xm+x, 141, ym-y),
|
||||
Block(block))
|
||||
editor.placeBlock((xm+y, 141, ym+x),
|
||||
Block(block))
|
||||
print(xm-x, ym+y)
|
||||
print(xm-y, ym-x)
|
||||
print(xm+x, ym-y)
|
||||
print(xm+y, ym+x)
|
||||
r = err
|
||||
update = False
|
||||
if (r <= y):
|
||||
y += 1
|
||||
update = True
|
||||
err += y*2+1
|
||||
if ((r > x or err > y)):
|
||||
if (pixel_perfect == True or update == False):
|
||||
x += 1
|
||||
err += x*2+1
|
||||
update = True
|
||||
if (x < 0):
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
def set_pixel(x, y, colour):
|
||||
editor = Editor(buffering=True)
|
||||
editor.placeBlock((x, 160, y),
|
||||
Block(colour))
|
||||
|
||||
|
||||
def x_line(x1, x2, y, colour):
|
||||
while x1 <= x2:
|
||||
set_pixel(x1, y, colour)
|
||||
x1 += 1
|
||||
|
||||
|
||||
def y_line(x, y1, y2, colour):
|
||||
while y1 <= y2:
|
||||
set_pixel(x, y1, colour)
|
||||
y1 += 1
|
||||
|
||||
|
||||
def circle2(xc, yc, inner, outer):
|
||||
# https://stackoverflow.com/questions/27755514/circle-with-thickness-drawing-algorithm
|
||||
xo = outer
|
||||
xi = inner
|
||||
y = 0
|
||||
erro = 1 - xo
|
||||
erri = 1 - xi
|
||||
|
||||
while xo >= y:
|
||||
colour = random.choices(("white_concrete", "red_concrete", "blue_concrete", "green_concrete",
|
||||
"yellow_concrete", "black_concrete", "purple_concrete", "pink_concrete"))[0]
|
||||
x_line(xc + xi, xc + xo, yc + y, colour)
|
||||
y_line(xc + y, yc + xi, yc + xo, colour)
|
||||
x_line(xc - xo, xc - xi, yc + y, colour)
|
||||
y_line(xc - y, yc + xi, yc + xo, colour)
|
||||
x_line(xc - xo, xc - xi, yc - y, colour)
|
||||
y_line(xc - y, yc - xo, yc - xi, colour)
|
||||
x_line(xc + xi, xc + xo, yc - y, colour)
|
||||
y_line(xc + y, yc - xo, yc - xi, colour)
|
||||
|
||||
y += 1
|
||||
|
||||
if erro < 0:
|
||||
erro += 2 * y + 1
|
||||
else:
|
||||
xo -= 1
|
||||
erro += 2 * (y - xo + 1)
|
||||
|
||||
if y > inner:
|
||||
xi = y
|
||||
else:
|
||||
if erri < 0:
|
||||
erri += 2 * y + 1
|
||||
else:
|
||||
xi -= 1
|
||||
erri += 2 * (y - xi + 1)
|
||||
|
||||
|
||||
# print("\n")
|
||||
# circle2(-1606, 758, 5, 15)
|
||||
# circle2(-1606, 758, 5, 5)
|
||||
# circle2(-1606, 758, 10, 10)
|
||||
circle2(-1606, 758, 15, 17)
|
||||
|
||||
|
||||
class LineOverlap(Enum):
|
||||
NONE = 0
|
||||
MAJOR = 1
|
||||
MINOR = 2
|
||||
|
||||
|
||||
class LineThicknessMode(Enum):
|
||||
MIDDLE = 0
|
||||
DRAW_COUNTERCLOCKWISE = 1
|
||||
DRAW_CLOCKWISE = 2
|
||||
|
||||
|
||||
class Point2D:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.x} {self.y})"
|
||||
|
||||
def copy(self):
|
||||
return Point2D(self.x, self.y)
|
||||
|
||||
def get_coordinates(self):
|
||||
return (self.x, self.y)
|
||||
|
||||
|
||||
def drawLineOverlap(start, end, overlap):
|
||||
y = 120
|
||||
block = random.choices(("white_concrete", "red_concrete", "blue_concrete", "green_concrete",
|
||||
"yellow_concrete", "black_concrete", "purple_concrete", "pink_concrete"))[0]
|
||||
print(block)
|
||||
editor = Editor(buffering=True)
|
||||
|
||||
start = start.copy()
|
||||
end = end.copy()
|
||||
|
||||
# Direction
|
||||
delta_x = end.x - start.x
|
||||
delta_y = end.y - start.y
|
||||
|
||||
if (delta_x < 0):
|
||||
delta_x = -delta_x
|
||||
step_x = -1
|
||||
else:
|
||||
step_x = +1
|
||||
|
||||
if (delta_y < 0):
|
||||
delta_y = -delta_y
|
||||
step_y = -1
|
||||
else:
|
||||
step_y = +1
|
||||
|
||||
delta_2x = 2*delta_x
|
||||
delta_2y = 2*delta_y
|
||||
|
||||
print(start.x, start.y)
|
||||
editor.placeBlock((start.x, y, start.y), Block(block))
|
||||
|
||||
if (delta_x > delta_y):
|
||||
error = delta_2y - delta_x
|
||||
while (start.x != end.x):
|
||||
start.x += step_x
|
||||
if (error >= 0):
|
||||
if (overlap == LineOverlap.MAJOR):
|
||||
print(start.x, start.y)
|
||||
editor.placeBlock((start.x, y, start.y),
|
||||
Block(block))
|
||||
|
||||
start.y += step_y
|
||||
if (overlap == LineOverlap.MINOR):
|
||||
print(start.x - step_x, start.y)
|
||||
editor.placeBlock((start.x - step_x, y, start.y),
|
||||
Block(block))
|
||||
error -= delta_2x
|
||||
error += delta_2y
|
||||
print(start.x, start.y)
|
||||
editor.placeBlock((start.x, y, start.y),
|
||||
Block(block))
|
||||
else:
|
||||
error = delta_2x - delta_y
|
||||
while (start.y != end.y):
|
||||
start.y += step_y
|
||||
if (error >= 0):
|
||||
if (overlap == LineOverlap.MAJOR):
|
||||
print(start)
|
||||
editor.placeBlock((start.x, y, start.y),
|
||||
Block(block))
|
||||
start.x += step_x
|
||||
if (overlap == LineOverlap.MINOR):
|
||||
print(start.x, start.y - step.y, start.z, )
|
||||
editor.placeBlock((start.x, y, start.y - step.y),
|
||||
Block(block))
|
||||
error -= delta_2y
|
||||
error += delta_2x
|
||||
print(start.x, start.y)
|
||||
editor.placeBlock((start.x, y, start.y),
|
||||
Block("white_concrete"))
|
||||
|
||||
|
||||
# drawLineOverlap(Point2D(-10, 0, 0,), Point2D(10, 0, 3),
|
||||
# LineOverlap.NONE)
|
||||
|
||||
|
||||
def drawThickLine(start, end, thickness, thickness_mode):
|
||||
delta_y = end.x - start.x
|
||||
delta_x = end.y - start.y
|
||||
|
||||
print("START", start)
|
||||
|
||||
swap = True
|
||||
if delta_x < 0:
|
||||
delta_x = -delta_x
|
||||
step_x = -1
|
||||
swap = not swap
|
||||
else:
|
||||
step_x = +1
|
||||
|
||||
if (delta_y < 0):
|
||||
delta_y = -delta_y
|
||||
step_y = -1
|
||||
swap = not swap
|
||||
else:
|
||||
step_y = +1
|
||||
|
||||
delta_2x = 2 * delta_x
|
||||
delta_2y = 2 * delta_y
|
||||
|
||||
draw_start_adjust_count = int(thickness / 2)
|
||||
if (thickness_mode == LineThicknessMode.DRAW_COUNTERCLOCKWISE):
|
||||
draw_start_adjust_count = thickness - 1
|
||||
elif (thickness_mode == LineThicknessMode.DRAW_CLOCKWISE):
|
||||
draw_start_adjust_count = 0
|
||||
print("START", start)
|
||||
if (delta_x >= delta_y):
|
||||
if swap:
|
||||
draw_start_adjust_count = (thickness - 1) - draw_start_adjust_count
|
||||
step_y = -step_y
|
||||
else:
|
||||
step_x = -step_x
|
||||
|
||||
error = delta_2y - delta_x
|
||||
for i in range(draw_start_adjust_count, 0, -1):
|
||||
print("START", start)
|
||||
start.x -= step_x
|
||||
end.x -= step_x
|
||||
if error >= 0:
|
||||
start.y -= step_y
|
||||
end.y -= step_y
|
||||
error -= delta_2x
|
||||
error += delta_2x
|
||||
print("START", start)
|
||||
print("First print")
|
||||
print(start, end)
|
||||
drawLineOverlap(start, end, LineOverlap.NONE)
|
||||
print(start, end)
|
||||
print("End print")
|
||||
|
||||
error = delta_2x - delta_x
|
||||
for i in range(thickness, 1, -1):
|
||||
start.x += step_x
|
||||
end.x += step_x
|
||||
overlap = LineOverlap.NONE
|
||||
if (error >= 0):
|
||||
start.y += step_y
|
||||
end.y += step_y
|
||||
error -= delta_2x
|
||||
overlap = LineOverlap.MAJOR
|
||||
error += delta_2y
|
||||
print("Second print")
|
||||
print(start, end)
|
||||
drawLineOverlap(start, end, overlap)
|
||||
print(start, end)
|
||||
print("End print")
|
||||
else:
|
||||
if swap:
|
||||
step_x = -step_x
|
||||
else:
|
||||
draw_start_adjust_count = (thickness - 1) - draw_start_adjust_count
|
||||
step_y = -step_y
|
||||
|
||||
error = delta_2x - delta_y
|
||||
for i in range(draw_start_adjust_count, 0, -1):
|
||||
start.y -= step_y
|
||||
end.y -= step_y
|
||||
if (error >= 0):
|
||||
start.x -= step_x
|
||||
end.x -= step_x
|
||||
error -= delta_2y
|
||||
error += delta_2x
|
||||
|
||||
print("Third line")
|
||||
print(start, end)
|
||||
drawLineOverlap(start, end, LineOverlap.NONE)
|
||||
print(start, end)
|
||||
print("End line")
|
||||
error = delta_2x - delta_y
|
||||
for i in range(thickness, 1, -1):
|
||||
start.y += step_y
|
||||
end.y += step_y
|
||||
overlap = LineOverlap.NONE
|
||||
if (error >= 0):
|
||||
start.x += step_x
|
||||
end.x += step_x
|
||||
error -= delta_2y
|
||||
overlap = LineOverlap.MAJOR
|
||||
error += delta_2x
|
||||
print("Fourth line")
|
||||
print(start, end)
|
||||
drawLineOverlap(start, end, overlap)
|
||||
print(start, end)
|
||||
print("End")
|
||||
|
||||
|
||||
print("SPACE\n\n")
|
||||
drawThickLine(Point2D(-1681, 864), Point2D(-1804, 920),
|
||||
21, LineThicknessMode.MIDDLE)
|
||||
Reference in New Issue
Block a user