diff --git a/cube.html b/cube.html
index 81b7e03..72c141a 100644
--- a/cube.html
+++ b/cube.html
@@ -40,21 +40,32 @@ hljs.highlightAll();
(size: list | Point,
center: bool = False)
A 3D primitive, cube. -Creates a cube in the first octant. When center is true, the cube is centered on the origin.
-See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#cube
A 3D primitive, cube.
+See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#cube
+Creates a cube in the first octant. When center
is True, the cube is centered on the origin.
x, y, z
sizesclass Cube(Object):
"""A 3D primitive, cube.
- Creates a cube in the first octant. When center is true, the cube is centered on the origin.
-
+
See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#cube
"""
def __init__(self, size: TUnion[list, Point], center: bool = False):
+ """
+ Creates a cube in the first octant. When `center` is True, the cube is centered on the origin.
+
+ Arguments:
+ - size: a Point object or a list of `x, y, z` sizes
+ - center: if True, the cube is centered on the origin
+ """
self.size = Point.c(size)
self.center = center
diff --git a/point.html b/point.html
index e8f3cf6..993c848 100644
--- a/point.html
+++ b/point.html
@@ -37,44 +37,47 @@ hljs.highlightAll();
class Point
-(coords)
+(coords: List[float])
-
-
Represents a point or vector in arbitrary dimensions
+Represents a point or vector in arbitrary number of dimensions
Expand source code
class Point:
- """Represents a point or vector in arbitrary dimensions"""
+ """Represents a point or vector in arbitrary number of dimensions"""
- def __init__(self, coords):
+ def __init__(self, coords: List[float]):
self.c = np.array(coords, dtype=NP_TYPE)
@classmethod
- def c(cls, coords: TUnion[list, 'Point']) -> 'Point':
- """Ensure coords is an instance of Point (idempotent)"""
+ def c(cls, coords: TUnion[list[float], 'Point']) -> 'Point':
+ """Ensure `coords` is an instance of Point (idempotent)"""
if isinstance(coords, Point):
return coords
return Point(coords)
def render(self) -> str:
- """Render the object into OpenSCAD code"""
+ """Render the point / vector into OpenSCAD code"""
return "[" + (",".join([str(c) for c in self.c])) + "]"
def render_stl(self) -> str:
+ """Render the point / vector into STL"""
return " ".join([str(c) for c in self.c])
def scale(self, x: float) -> 'Point':
- """Scale the current vector/point by a scalar"""
+ """Scale the current point / vector by the scalar `x`"""
return self.__class__(self.c * x)
def add(self, p: 'Point') -> 'Point':
+ """Add another point / vector `p` to the current one"""
assert isinstance(p, Point)
assert self.dim() == p.dim()
return self.__class__(self.c + p.c)
def sub(self, p: 'Point') -> 'Point':
+ """Subtract another point / vector `p` from the current one"""
assert isinstance(p, Point)
assert self.dim() == p.dim()
return self.__class__(self.c - p.c)
@@ -92,17 +95,18 @@ hljs.highlightAll();
return np.sqrt(np.square(self.c).sum())
def norm(self) -> 'Point':
+ """Return a normalized version of the vector (scaled to length 1)"""
l = self.length()
if l == 0:
- raise Exception("normalising 0 vector")
+ raise Exception("Attempted to normalise 0 vector")
return self.__class__(self.c / self.length())
def dot(self, p: 'Point') -> float:
- """Return the dot product"""
+ """Return the dot product of the current vector and `p`"""
return np.dot(self.c, p.c)
def cross(self, p: 'Point') -> 'Point':
- """Return the cross product"""
+ """Return the cross product of the current vector and `p`"""
assert self.dim() == 3
assert p.dim() == 3
return Point([
@@ -113,25 +117,36 @@ hljs.highlightAll();
])
def eq(self, p: 'Point') -> bool:
+ """Return whether the current point / vector and `p` are equal"""
return (self.c == p.c).all()
def lt(self, p: 'Point') -> bool:
+ """Return whether the current vector is smaller than `p` in each dimension"""
return (self.c < p.c).all()
def le(self, p: 'Point') -> bool:
+ """Return whether the current vector is smaller or equal to `p` in each dimension"""
return (self.c <= p.c).all()
def gt(self, p: 'Point') -> bool:
+ """Return whether the current vector is greater than `p` in each dimension"""
return (self.c > p.c).all()
def ge(self, p: 'Point') -> bool:
+ """Return whether the current vector is greater or equal to `p` in each dimension"""
return (self.c >= p.c).all()
def allclose(self, p: 'Point') -> bool:
+ """Return whether the current point / vector and `p` are close to each other"""
return self.c.shape == p.c.shape and np.allclose(self.c, p.c)
def angle(self, p: 'Point', mode: str = "deg") -> float:
- """Return the angle between two vectors in degrees or radians"""
+ """Return the angle between two vectors in degrees or radians
+
+ Arguments:
+ - p: a Point object
+ - mode: "deg" | "rad"
+ """
r = self.dot(p)
r = r / self.length() / p.length()
r = math.acos(r)
@@ -142,7 +157,11 @@ hljs.highlightAll();
raise ValueError("Unknown mode")
def z_slope(self, mode: str = "deg") -> float:
- """Return the slope of a vector in degrees or radians"""
+ """Return the slope of a vector in degrees or radians
+
+ Arguments:
+ - mode: "deg" | "rad"
+ """
r = self.c[2] / self.length()
r = math.asin(r)
if mode == "rad":
@@ -152,7 +171,12 @@ hljs.highlightAll();
raise ValueError("Unknown mode")
def rotate(self, coords, angle: float) -> 'Point':
- """Rotate. coords is a list of 2 coordinate indices that we rotate"""
+ """Rotate the current vector
+
+ Arguments:
+ - coords: A list of 2 coordinate indices to rotate
+ - angle: the angle to rotate by, in degrees
+ """
assert len(coords) == 2
ca, cb = coords
s = np.sin(angle / 180. * np.pi)
@@ -165,26 +189,33 @@ hljs.highlightAll();
# Operator overloading
def __add__(self, other):
+ """Use `p1 + p2` to add two vectors"""
return self.add(other)
def __radd__(self, other):
+ """Use `p1 + p2` to add two vectors"""
assert isinstance(other, Point)
return other.add(self)
def __sub__(self, other):
+ """Use `p1 - p2` to subtract two vectors"""
return self.sub(other)
def __rsub__(self, other):
+ """Use `p1 - p2` to subtract two vectors"""
assert isinstance(other, Point)
return other.sub(self)
def __mul__(self, other):
+ """Use `p * x` to scale a vector"""
return self.scale(other)
def __rmul__(self, other):
+ """Use `x * p` to scale a vector"""
return self.scale(other)
def __neg__(self):
+ """Use `-p` to negate a vector"""
return self.scale(-1.)
Static methods
@@ -193,34 +224,69 @@ hljs.highlightAll();
def c(coords: list | ForwardRef('Point')) ‑> Point
Ensure coords is an instance of Point (idempotent)
Ensure coords
is an instance of Point (idempotent)
+def __add__(self, other)
+
Use p1 + p2
to add two vectors
+def __mul__(self, other)
+
Use p * x
to scale a vector
+def __neg__(self)
+
Use -p
to negate a vector
+def __rmul__(self, other)
+
Use x * p
to scale a vector
+def __sub__(self, other)
+
Use p1 - p2
to subtract two vectors
def add(self,
p: Point) ‑> Point
Add another point / vector p
to the current one
def allclose(self,
p: Point) ‑> bool
Return whether the current point / vector and p
are close to each other
def angle(self,
p: Point,
mode: str = 'deg') ‑> float
Return the angle between two vectors in degrees or radians
Return the angle between two vectors in degrees or radians
+
def cross(self,
p: Point) ‑> Point
Return the cross product
Return the cross product of the current vector and p
def dim(self) ‑> int
@@ -232,25 +298,25 @@ hljs.highlightAll();
def dot(self,
p: Point) ‑> float
Return the dot product
Return the dot product of the current vector and p
def eq(self,
p: Point) ‑> bool
Return whether the current point / vector and p
are equal
def ge(self,
p: Point) ‑> bool
Return whether the current vector is greater or equal to p
in each dimension
def gt(self,
p: Point) ‑> bool
Return whether the current vector is greater than p
in each dimension
def is_zero(self) ‑> bool
@@ -262,7 +328,7 @@ hljs.highlightAll();
def le(self,
p: Point) ‑> bool
Return whether the current vector is smaller or equal to p
in each dimension
def length(self) ‑> float
@@ -274,49 +340,58 @@ hljs.highlightAll();
def lt(self,
p: Point) ‑> bool
Return whether the current vector is smaller than p
in each dimension
def norm(self) ‑> Point
Return a normalized version of the vector (scaled to length 1)
def render(self) ‑> str
Render the object into OpenSCAD code
Render the point / vector into OpenSCAD code
def render_stl(self) ‑> str
Render the point / vector into STL
def rotate(self, coords, angle: float) ‑> Point
Rotate. coords is a list of 2 coordinate indices that we rotate
Rotate the current vector
+
def scale(self, x: float) ‑> Point
Scale the current vector/point by a scalar
Scale the current point / vector by the scalar x
def sub(self,
p: Point) ‑> Point
Subtract another point / vector p
from the current one
def z_slope(self, mode: str = 'deg') ‑> float
Return the slope of a vector in degrees or radians
Return the slope of a vector in degrees or radians
+Point
__add__
__mul__
__neg__
__rmul__
__sub__
add
allclose
angle
A 3D primitive, a polyhedron defined by a list of points and faces. -Faces are defined by lists of point indices. The points of a face must be listed clockwise when -looking at the face from the outside inward. -Nonplanar faces should be triangulated by OpenSCAD.
-See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#polyhedron
See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#polyhedron
+class Polyhedron(Object):
"""A 3D primitive, a polyhedron defined by a list of points and faces.
- Faces are defined by lists of point indices. The points of a face must be listed clockwise when
- looking at the face from the outside inward.
- Nonplanar faces should be triangulated by OpenSCAD.
+ Nonplanar faces will be triangulated by OpenSCAD.
See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#polyhedron
"""
def __init__(self, points: List[TUnion[list, Point]], faces: List[list], convexity: int = 10):
+ """
+ Arguments:
+ - points: a list of Point objects or coordinate tuples defining the vertices
+ - faces: defines the faces as a list of lists of vertex indices. The points of a face must be listed clockwise when looking at the face from the outside inward.
+ """
self.points = [Point.c(p) for p in points]
self.faces = faces
self.convexity = convexity