A comprehensive Python package for creating, reading, modifying, and writing DXF (Drawing Exchange Format) documents with support for multiple DXF versions.
—
Comprehensive mathematical utilities for 2D/3D geometry, transformations, curve calculations, and geometric constructions. The math package provides the mathematical foundation for all geometric operations in ezdxf.
2D and 3D vector classes with full arithmetic operations, geometric calculations, and utility functions.
class Vec2:
"""2D vector class"""
def __init__(self, x: float = 0, y: float = 0): ...
@property
def x(self) -> float: ...
@property
def y(self) -> float: ...
def __add__(self, other: 'Vec2') -> 'Vec2': ...
def __sub__(self, other: 'Vec2') -> 'Vec2': ...
def __mul__(self, scalar: float) -> 'Vec2': ...
def __truediv__(self, scalar: float) -> 'Vec2': ...
def dot(self, other: 'Vec2') -> float: ...
def cross(self, other: 'Vec2') -> float: ...
def magnitude(self) -> float: ...
def normalize(self) -> 'Vec2': ...
def angle(self) -> float: ...
def rotate(self, angle: float) -> 'Vec2': ...
class Vec3:
"""3D vector class"""
def __init__(self, x: float = 0, y: float = 0, z: float = 0): ...
@property
def x(self) -> float: ...
@property
def y(self) -> float: ...
@property
def z(self) -> float: ...
@property
def xy(self) -> Vec2: ...
def __add__(self, other: 'Vec3') -> 'Vec3': ...
def __sub__(self, other: 'Vec3') -> 'Vec3': ...
def __mul__(self, scalar: float) -> 'Vec3': ...
def __truediv__(self, scalar: float) -> 'Vec3': ...
def dot(self, other: 'Vec3') -> float: ...
def cross(self, other: 'Vec3') -> 'Vec3': ...
def magnitude(self) -> float: ...
def normalize(self) -> 'Vec3': ...
def distance(self, other: 'Vec3') -> float: ...
def angle_between(self, other: 'Vec3') -> float: ...
def project(self, other: 'Vec3') -> 'Vec3': ...
def rotate_axis(self, axis: 'Vec3', angle: float) -> 'Vec3': ...Usage examples:
from ezdxf.math import Vec2, Vec3
# 2D vector operations
v1 = Vec2(3, 4)
v2 = Vec2(1, 2)
v3 = v1 + v2 # Vec2(4, 6)
length = v1.magnitude() # 5.0
unit_v1 = v1.normalize() # Vec2(0.6, 0.8)
# 3D vector operations
a = Vec3(1, 0, 0)
b = Vec3(0, 1, 0)
c = a.cross(b) # Vec3(0, 0, 1) - Z axis
dot_product = a.dot(b) # 0.0
distance = a.distance(b) # ~1.4144x4 transformation matrices for 3D geometric operations including translation, rotation, scaling, and projection.
class Matrix44:
"""4x4 transformation matrix"""
def __init__(self, values = None): ...
@classmethod
def identity(cls) -> 'Matrix44':
"""Create identity matrix"""
@classmethod
def translate(cls, dx: float, dy: float, dz: float) -> 'Matrix44':
"""Create translation matrix"""
@classmethod
def scale(cls, sx: float, sy: float = None, sz: float = None) -> 'Matrix44':
"""Create scaling matrix"""
@classmethod
def x_rotate(cls, angle: float) -> 'Matrix44':
"""Create X-axis rotation matrix (angle in radians)"""
@classmethod
def y_rotate(cls, angle: float) -> 'Matrix44':
"""Create Y-axis rotation matrix (angle in radians)"""
@classmethod
def z_rotate(cls, angle: float) -> 'Matrix44':
"""Create Z-axis rotation matrix (angle in radians)"""
@classmethod
def axis_rotate(cls, axis: Vec3, angle: float) -> 'Matrix44':
"""Create rotation matrix around arbitrary axis"""
def __mul__(self, other) -> 'Matrix44':
"""Matrix multiplication"""
def transform(self, vector: Vec3) -> Vec3:
"""Transform vector by matrix"""
def transform_vertices(self, vertices) -> List[Vec3]:
"""Transform multiple vertices"""
def inverse(self) -> 'Matrix44':
"""Calculate matrix inverse"""
def transpose(self) -> 'Matrix44':
"""Calculate matrix transpose"""Usage examples:
from ezdxf.math import Matrix44, Vec3
import math
# Create transformation matrices
translate = Matrix44.translate(10, 20, 5)
scale = Matrix44.scale(2, 2, 1) # Scale by 2 in X and Y
rotate = Matrix44.z_rotate(math.radians(45)) # Rotate 45° around Z
# Combine transformations
combined = translate @ rotate @ scale # Matrix multiplication
# Transform points
point = Vec3(1, 1, 0)
transformed = combined.transform(point)
# Transform multiple points
points = [Vec3(0, 0, 0), Vec3(1, 0, 0), Vec3(1, 1, 0)]
transformed_points = combined.transform_vertices(points)Advanced curve mathematics including Bézier curves, B-splines, and specialized curve types.
class Bezier:
"""General Bézier curve class"""
def __init__(self, control_points): ...
@property
def control_points(self) -> List[Vec3]:
"""Control points defining the curve"""
def point(self, t: float) -> Vec3:
"""Evaluate curve at parameter t (0-1)"""
def tangent(self, t: float) -> Vec3:
"""Tangent vector at parameter t"""
def approximate(self, segments: int) -> List[Vec3]:
"""Approximate curve with line segments"""
class Bezier3P:
"""3-point Bézier curve (quadratic)"""
def __init__(self, start: Vec3, control: Vec3, end: Vec3): ...
class Bezier4P:
"""4-point Bézier curve (cubic)"""
def __init__(self, start: Vec3, ctrl1: Vec3, ctrl2: Vec3, end: Vec3): ...
class BSpline:
"""B-spline curve representation"""
def __init__(self, control_points, order: int = 4, knots = None, weights = None): ...
@property
def control_points(self) -> List[Vec3]:
"""Control points"""
@property
def order(self) -> int:
"""Curve order (degree + 1)"""
@property
def knots(self) -> List[float]:
"""Knot vector"""
@property
def weights(self) -> List[float]:
"""Control point weights (for NURBS)"""
def point(self, t: float) -> Vec3:
"""Evaluate curve at parameter t"""
def insert_knot(self, u: float) -> 'BSpline':
"""Insert knot at parameter u"""
def approximate(self, segments: int) -> List[Vec3]:
"""Approximate curve with line segments"""
class EulerSpiral:
"""Euler spiral (clothoid) curve"""
def __init__(self, radius: float = 1000, curvature: float = 1, length: float = 100): ...
def point(self, t: float) -> Vec3:
"""Point at parameter t along the spiral"""
def approximate(self, segments: int) -> List[Vec3]:
"""Approximate spiral with line segments"""2D and 3D geometric construction utilities for lines, circles, ellipses, and other geometric primitives.
class ConstructionLine:
"""2D construction line utilities"""
def __init__(self, start: Vec2, end: Vec2): ...
@classmethod
def from_angle(cls, start: Vec2, angle: float, length: float = 1): ...
def intersect(self, other: 'ConstructionLine') -> Vec2:
"""Find intersection point with another line"""
def distance_to_point(self, point: Vec2) -> float:
"""Distance from point to line"""
def is_parallel(self, other: 'ConstructionLine') -> bool:
"""Check if lines are parallel"""
class ConstructionRay:
"""2D construction ray (semi-infinite line)"""
def __init__(self, start: Vec2, direction: Vec2): ...
class ConstructionBox:
"""2D rectangle construction utilities"""
def __init__(self, center: Vec2, width: float, height: float, angle: float = 0): ...
@property
def corners(self) -> List[Vec2]:
"""Rectangle corner points"""
def contains_point(self, point: Vec2) -> bool:
"""Check if point is inside rectangle"""
class ConstructionEllipse:
"""3D ellipse construction and manipulation"""
def __init__(self, center: Vec3, major_axis: Vec3, minor_axis: Vec3,
start_param: float = 0, end_param: float = 2*pi): ...
@property
def center(self) -> Vec3: ...
@property
def major_axis(self) -> Vec3: ...
@property
def minor_axis(self) -> Vec3: ...
def point(self, param: float) -> Vec3:
"""Point at parameter value"""
def tangent(self, param: float) -> Vec3:
"""Tangent vector at parameter"""
def approximate(self, segments: int) -> List[Vec3]:
"""Approximate ellipse with line segments"""Collection of utility functions for common geometric calculations and operations.
def distance(p1, p2) -> float:
"""Calculate distance between two points"""
def lerp(p1, p2, factor: float):
"""Linear interpolation between points"""
def has_clockwise_orientation(vertices) -> bool:
"""Check if 2D vertices have clockwise orientation"""
def is_point_in_polygon_2d(point, polygon) -> bool:
"""Test if point is inside 2D polygon"""
def intersection_line_line_2d(line1, line2):
"""Calculate 2D line-line intersection"""
def intersection_ray_ray_3d(ray1, ray2):
"""Calculate 3D ray-ray intersection"""
def world_mercator_to_gps(x: float, y: float) -> tuple:
"""Convert Web Mercator coordinates to GPS (lat, lon)"""
def gps_to_world_mercator(lat: float, lon: float) -> tuple:
"""Convert GPS coordinates to Web Mercator (x, y)"""
def close_vectors(a, b, abs_tol: float = 1e-12) -> bool:
"""Compare vector sequences for equality within tolerance"""Specialized functions for B-spline curve fitting, interpolation, and conversion.
def fit_points_to_cad_cv(points, *, method: str = 'chord', tangents = None) -> BSpline:
"""
Fit points to B-spline control vertices.
Parameters:
- points: data points to fit
- method: parameterization method ('chord', 'centripetal', 'uniform')
- tangents: optional start/end tangent vectors
Returns:
BSpline: Fitted B-spline curve
"""
def global_bspline_interpolation(points, *, degree: int = 3, method: str = 'chord',
tangents = None) -> BSpline:
"""
Global B-spline interpolation through points.
Parameters:
- points: points to interpolate
- degree: spline degree (1-3)
- method: parameterization method
- tangents: optional tangent constraints
Returns:
BSpline: Interpolating B-spline
"""
def local_cubic_bspline_interpolation(points, *, method: str = 'chord',
tangents = None) -> BSpline:
"""Local cubic B-spline interpolation"""
def rational_bspline_from_arc(arc, *, segments: int = 1) -> BSpline:
"""Create rational B-spline from circular arc"""
def rational_bspline_from_ellipse(ellipse, *, segments: int = 1) -> BSpline:
"""Create rational B-spline from ellipse"""Advanced mathematical utilities for specific applications and specialized calculations.
class BarycentricCoordinates:
"""Barycentric coordinate system for triangular interpolation"""
def __init__(self, triangle): ...
def from_cartesian(self, point) -> tuple:
"""Convert Cartesian coordinates to barycentric"""
def to_cartesian(self, u: float, v: float, w: float):
"""Convert barycentric coordinates to Cartesian"""
class Plane:
"""3D plane representation and operations"""
def __init__(self, normal: Vec3, distance: float): ...
@classmethod
def from_3_points(cls, p1: Vec3, p2: Vec3, p3: Vec3) -> 'Plane': ...
def distance_to_point(self, point: Vec3) -> float:
"""Signed distance from point to plane"""
def intersect_line(self, start: Vec3, end: Vec3) -> Vec3:
"""Find line-plane intersection"""
def mapbox_earcut_2d(exterior, holes = None) -> List[int]:
"""
2D polygon triangulation using earcut algorithm.
Parameters:
- exterior: exterior polygon vertices
- holes: list of hole polygon vertices
Returns:
List[int]: Triangle indices (3 indices per triangle)
"""
def mapbox_earcut_3d(points, holes = None) -> List[int]:
"""3D polygon triangulation projected to best-fit plane"""# Type aliases for flexibility
AnyVec = Union[Vec2, Vec3, Sequence[float]]
UVec = Union[Vec2, Vec3, Vertex]
# Constants
X_AXIS: Vec3 # (1, 0, 0)
Y_AXIS: Vec3 # (0, 1, 0)
Z_AXIS: Vec3 # (0, 0, 1)
NULLVEC: Vec3 # (0, 0, 0)
# Geometric primitives
Vertex = Tuple[float, float, float]Usage examples:
from ezdxf.math import *
import math
# Vector operations
v1 = Vec3(1, 2, 3)
v2 = Vec3(4, 5, 6)
v3 = v1 + v2 # Vec3(5, 7, 9)
v4 = v1.cross(v2) # Cross product
# Matrix transformations
m1 = Matrix44.translate(10, 20, 0)
m2 = Matrix44.z_rotate(math.radians(45))
combined = m1 @ m2 # Translate then rotate
# Curve operations
points = [Vec3(0, 0, 0), Vec3(1, 1, 0), Vec3(2, 0, 0), Vec3(3, 1, 0)]
spline = global_bspline_interpolation(points, degree=3)
curve_points = spline.approximate(20) # 20 line segments
# Geometric utilities
poly = [Vec2(0, 0), Vec2(4, 0), Vec2(4, 3), Vec2(0, 3)]
test_point = Vec2(2, 1.5)
inside = is_point_in_polygon_2d(test_point, poly) # TrueInstall with Tessl CLI
npx tessl i tessl/pypi-ezdxf