The Mesh Face
1 min read•1 page
The Atomic Surface
While a Polygon is an abstract mathematical boundary that implies an area, a Mesh Face is the absolute simplest form of physical surface in a computer. It is the atomic pixel of 3D geometry.
There are two primary types: Triangles (3 vertices) and Quads (4 vertices). Triangles are always perfectly flat, while Quads are simpler to model but can become non-planar.The Illusion of Smoothness: There are no true curves on a computer screen. Every smooth character in a video game is actually made of thousands of tiny, perfectly flat triangles or quadrilaterals.
2 min read•1 page
Memory & Storage
A Mesh Face does not store coordinate data itself. Instead, it stores an array of integer Indices that point to a master list of Verticesstored by the parent Mesh.
python
1class MeshFace:2 """3 Represents a single triangle or quad face in a mesh.4 Stores indices pointing to a master vertex array.5 """6 def __init__(self, a: int, b: int, c: int, d: int = None):7 self.A = int(a)8 self.B = int(b)9 self.C = int(c)10 self.D = int(d) if d is not None else int(c)
By pointing to shared vertices, adjacent faces can connect without duplicating coordinate data in memory.
2 min read•1 page
Face Normal:
A face normal is a vector that points strictly outward, perpendicular to the face surface. It is calculated by taking the Cross Product of two of its edges. The order of vertices (winding) determines which way the normal points (Right-Hand Rule).
python
1def MeshFaceNormal(ptA: 'Point3d', ptB: 'Point3d', ptC: 'Point3d') -> 'Vector3d':2 """Calculates the normal vector of a triangular face."""34 # 1. Create two edge vectors5 edge1 = ptB - ptA6 edge2 = ptC - ptA78 # 2. Compute cross product9 normal = Vector3d.CrossProduct(edge1, edge2)1011 # 3. Unitize the normal (make length 1)12 normal.Unitize()1314 return normal
1 min read•1 page
Winding & Flip:
The order of indices (winding order) defines which side of a face is the "front" and which is the "back". Reversing this order flips the direction of the face normal.
python
1class MeshFace:2 def reverse(self) -> None:3 """Reverses winding order, flipping the face normal."""4 if self.is_triangle:5 self.A, self.C = self.C, self.A6 else:7 self.A, self.D = self.D, self.A8 self.B, self.C = self.C, self.B
Normals are computed using the cross product of edges (Right-Hand Rule). Swapping vertex positions (e.g., A and C) changes the winding direction, instantly reversing the normal vector.
Flip Winding
2 min read•1 page
Face Area:
The area of a triangular face can be efficiently calculated using the length of the cross product of two of its edges. For a Quad face, it is split into two triangles and their areas are summed.
python
1def MeshFaceArea(ptA: 'Point3d', ptB: 'Point3d', ptC: 'Point3d') -> float:2 """Calculates the area of a triangular face."""34 # 1. Create two edge vectors5 edge1 = ptB - ptA6 edge2 = ptC - ptA78 # 2. The magnitude of the cross product of two vectors9 # equals the area of the parallelogram they form.10 cross = Vector3d.CrossProduct(edge1, edge2)11 parallelogram_area = cross.Length1213 # 3. Triangle area is half of the parallelogram area14 return parallelogram_area * 0.5
2 min read•1 page
Face Centroid:
The Centroid of a mesh face is its geometric center. It is calculated by taking the average of the coordinates of its vertices. Centroids are useful for placing labels, calculating distance offsets, or placing annotations.
python
1def get_face_centroid(vertices: list[Point3d]) -> Point3d:2 # The centroid of a face is the mathematical average of its vertex coordinates.3 n = len(vertices)4 if n == 0:5 return Point3d.Origin67 sum_x = sum(pt.X for pt in vertices)8 sum_y = sum(pt.Y for pt in vertices)9 sum_z = sum(pt.Z for pt in vertices)1011 return Point3d(sum_x / n, sum_y / n, sum_z / n)
1 min read•1 page
Move Vertices:
You do not move a Mesh Face directly. The face doesn't own its location — it only owns integer pointers. You move the parent vertices that its indices point to. If you move vertex
A, the face stretches to accommodate.python
1# You cannot do: face.Move(vector)2# You must do:3parent_mesh.Vertices[face.A] += motion_vector4parent_mesh.Vertices[face.B] += motion_vector5# ... and so on for each index
Vertex A → X
1.50Vertex A → Y
1.001 min read•1 page
Scale Vertices:
You cannot scale a Mesh Face independently without tearing it away from its neighboring faces. Scaling must happen to the parent pool.
python
1# Scale all vertices referenced by this face from the origin2for idx in [face.A, face.B, face.C, face.D]:3 parent_mesh.Vertices[idx] *= scale_factor
Scale Factor
1.502 min read•1 page
Rotate Vertices:
Like translation and scaling, rotation is applied to the master vertex array. The face simply re-renders based on the new positions of its designated corners.
python
1# Rotate vertex positions around a center point2for idx in [face.A, face.B, face.C, face.D]:3 v = parent_mesh.Vertices[idx]4 dx = v.X - center.X5 dy = v.Y - center.Y6 v.X = center.X + dx * cos(angle) - dy * sin(angle)7 v.Y = center.Y + dx * sin(angle) + dy * cos(angle)
Angle (°)
45.002 min read•1 page
Non-Planar Quad:
Triangles are always perfectly flat — any 3 points define a unique plane. A quadrilateral (4 points), however, can easily become bent or twisted in 3D space. Rendering engines handle non-planar quads by secretly triangulating them.
python
1def IsNonPlanar(self, vertices: list, tolerance: float = 0.001) -> bool:2 """A quad is non-planar if vertex D deviates from plane ABC."""3 if self.IsTriangle: return False45 a, b, c, d = [vertices[idx] for idx in [self.A, self.B, self.C, self.D]]6 normal = (b - a).CrossProduct(c - a)7 return abs(normal * (d - a)) > tolerance
Vertex D Warp (Z)
2.003 min read•1 page
Barycentric Coordinates:
Barycentric Coordinates define the position of a point
P relative to a triangle's vertices (A, B, C). Any point on the plane is represented as P = u*A + v*B + w*C where u + v + w = 1.0. If all coordinates are between 0 and 1, the point is inside the triangle.python
1def calculate_barycentric(ptA: Point3d, ptB: Point3d, ptC: Point3d, ptP: Point3d):2 # Calculates barycentric coordinates (u, v, w) of point P relative to triangle ABC.3 v0 = ptB - ptA4 v1 = ptC - ptA5 v2 = ptP - ptA67 d00 = v0 * v08 d01 = v0 * v19 d11 = v1 * v110 d20 = v2 * v011 d21 = v2 * v11213 denom = d00 * d11 - d01 * d0114 if abs(denom) < 1e-9:15 return 0.0, 0.0, 0.0 # Collinear/degenerate triangle1617 v = (d11 * d20 - d01 * d21) / denom18 w = (d00 * d21 - d01 * d20) / denom19 u = 1.0 - v - w2021 return u, v, w
Point X
0.00Point Y
0.002 min read•1 page
GetConnectedFaces:
Finds which faces share a common edge, forming the network of the mesh.
A mesh is not just a collection of disconnected triangles; it's a connected web. Topology maps out this connectivity, allowing algorithms to "walk" from one face to its neighbors. Will go more in depth when covering mesh topology.
python
1def get_adjacent_faces(faces: list[list[int]], face_idx: int) -> list[int]:2 """Returns indices of faces sharing an edge with the face at face_idx."""3 target_face = faces[face_idx]4 adjacent = []56 # Helper to get edges of a face (pairs of vertices)7 def get_edges(face):8 n = len(face)9 return {frozenset([face[i], face[(i + 1) % n]]) for i in range(n)}1011 target_edges = get_edges(target_face)1213 for idx, face in enumerate(faces):14 if idx == face_idx:15 continue16 # If face shares any edge with target face17 face_edges = get_edges(face)18 if target_edges.intersection(face_edges):19 adjacent.append(idx)2021 return adjacent
This concept is required for smoothing meshes, computing vertex normals, unwrapping UVs, and flood-fill selections.
2 min read•1 page
Aspect Ratio:
A common metric to determine the "quality" of a mesh face for simulation and fabrication.
python
1# Manual calculation based on edge lengths23def AspectRatio(face: MeshFace, mesh: Mesh) -> float:4 """Calculates the ratio between the longest and shortest edge."""5 # Get physical 3D vertices6 verts = [mesh.Vertices[i] for i in [face.A, face.B, face.C, face.D] if i != face.C]7 if face.IsQuad:8 verts = [mesh.Vertices[i] for i in [face.A, face.B, face.C, face.D]]9 else:10 verts = [mesh.Vertices[i] for i in [face.A, face.B, face.C]]1112 # Calculate all edge lengths13 edges = [v2.DistanceTo(v1) for v1, v2 in zip(verts, verts[1:] + [verts[0]])]1415 # Aspect Ratio = Longest Edge / Shortest Edge16 return max(edges) / min(edges)
A face with an aspect ratio of 1.0 is perfectly uniform (like an equilateral triangle or a square). As a face is stretched, its aspect ratio increases.
Stretch Face
2.504 min read•1 page
Circumcircle:
The unique circle that perfectly touches all three vertices of a triangle.
Every triangle in existence has exactly one circumcircle. The center of this circle is called the "Circumcenter", and it represents the point equidistant from all three vertices.
python
1def Circumcircle(A: Point3d, B: Point3d, C: Point3d) -> Circle:2 """Finds the unique circle passing through all 3 vertices."""3 # Midpoints of AB and BC4 midAB = (A + B) * 0.55 midBC = (B + C) * 0.567 # Directions8 dirAB = B - A9 dirBC = C - B1011 # Perpendicular normals in 2D plane12 perpAB = Vector3d(-dirAB.Y, dirAB.X, 0).Unitize()13 perpBC = Vector3d(-dirBC.Y, dirBC.X, 0).Unitize()1415 # 2D line intersection of perpendicular bisectors16 x1, y1 = midAB.X, midAB.Y17 x2, y2 = midAB.X + perpAB.X, midAB.Y + perpAB.Y18 x3, y3 = midBC.X, midBC.Y19 x4, y4 = midBC.X + perpBC.X, midBC.Y + perpBC.Y2021 denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)22 if abs(denom) < 1e-9:23 return None2425 cx = ((x1*y2 - y1*x2)*(x3 - x4) - (x1 - x2)*(x3*y4 - y3*x4)) / denom26 cy = ((x1*y2 - y1*x2)*(y3 - y4) - (y1 - y2)*(x3*y4 - y3*x4)) / denom2728 center = Point3d(cx, cy, 0)29 radius = (center - A).Length30 return Circle(center, radius)
This concept is the mathematical engine behind Delaunay Triangulation — the global standard algorithm for generating meshes from point clouds. Delaunay ensures that no vertex ever falls inside the circumcircle of any other triangle, maximizing the aspect ratio (quality) of the mesh.
Move Vertex A
0.002 min read•1 page
Triangulate:
Triangulation splits a multi-sided polygon or Quad face into flat triangular faces.
python
1def triangulate(face: MeshFace) -> list[tuple[int, int, int]]:2 """Splits a face into triangular faces (tuples of 3 vertex indices)."""3 if face.IsTriangle:4 return [(face.A, face.B, face.C)]56 # Quad face (A, B, C, D) splits into (A, B, C) and (A, C, D)7 return [(face.A, face.B, face.C), (face.A, face.C, face.D)]
GPUs only render triangles natively. Any Quad or N-gon face is internally split into triangles before rendering or running structural finite element analysis (FEA).
Split Diagonal (BD)
6 min read•2 pages
Closest Point:
Finding the Closest Point on a polygon boundary is a search operation. The algorithm decomposes the polygon into a series of line segments, projects the test point onto every segment, and returns the result with the shortest absolute distance.
python
1def closest_point(face: MeshFace, vertices: list[Point3d], test_pt: Point3d) -> Point3d:2 """Projects a point onto the surface of a face."""3 pts = [vertices[face.A], vertices[face.B], vertices[face.C]]45 def closest_pt_on_tri(a, b, c, p):6 ab, ac, ap = b - a, c - a, p - a7 d1, d2 = ab.dot(ap), ac.dot(ap)8 if d1 <= 0 and d2 <= 0: return a910 bp = p - b11 d3, d4 = ab.dot(bp), ac.dot(bp)12 if d3 >= 0 and d4 <= d3: return b1314 vc = d1 * d4 - d3 * d215 if vc <= 0 and d1 >= 0 and d3 <= 0:16 return a + ab * (d1 / (d1 - d3))1718 cp = p - c19 d5, d6 = ab.dot(cp), ac.dot(cp)20 if d6 >= 0 and d5 <= d6: return c2122 vb = d5 * d2 - d1 * d623 if vb <= 0 and d2 >= 0 and d6 <= 0:24 return a + ac * (d2 / (d2 - d6))2526 va = d3 * d6 - d5 * d427 if va <= 0 and (d4 - d3) >= 0 and (d5 - d6) >= 0:28 return b + (c - b) * ((d4 - d3) / ((d4 - d3) + (d5 - d6)))2930 denom = 1.0 / (va + vb + vc)31 return a + ab * (vb * denom) + ac * (vc * denom)3233 p1 = closest_pt_on_tri(pts[0], pts[1], pts[2], test_pt)34 if not face.IsQuad:35 return p13637 p2 = closest_pt_on_tri(vertices[face.A], vertices[face.C], vertices[face.D], test_pt)38 return p1 if (test_pt - p1).Length < (test_pt - p2).Length else p2
Finding the point on a face that is closest to an external point is a cornerstone of collision and interaction. The "closest point" is found by projecting the test point onto the plane of the face and then "clamping" it to the boundary using Barycentric Coordinates.
Search Pt X
1.00Search Pt Y
1.00