Files
orange 4043e82f2c Documents pattern scanning API
Adds comprehensive documentation for the pattern scanning API.

Details parsing behavior, complexity, and usage examples.
Includes troubleshooting tips and minimal test sketches.
Clarifies edge-case handling and implementation notes.
2025-10-31 16:25:56 +03:00

2.9 KiB
Raw Permalink Blame History

omath::primitives::create_plane — Build an oriented quad (2 triangles)

Header: your projects primitives/plane.hpp Namespace: omath::primitives Depends on: omath::Triangle<omath::Vector3<float>>, omath::Vector3<float>

[[nodiscard]]
std::array<Triangle<Vector3<float>>, 2>
create_plane(const Vector3<float>& vertex_a,
             const Vector3<float>& vertex_b,
             const Vector3<float>& direction,
             float size) noexcept;

What it does

Creates a rectangle (quad) in 3D oriented by the edge A→B and a second in-plane direction. The quad is returned as two triangles suitable for rendering or collision.

  • Edge axis: e = vertex_b - vertex_a
  • Width axis: “direction”, projected to be perpendicular to e so the quad is planar and well-formed.
  • Normal (by right-hand rule): n ∝ e × width.

Sizing convention Typical construction uses half-width = size along the (normalized, orthogonalized) direction, i.e. the total width is 2*size. If your implementation interprets size as full width, adjust your expectations accordingly.


Parameters

  • vertex_a, vertex_b — two adjacent quad vertices defining the long edge of the plane.
  • direction — a vector indicating the cross-edge direction within the plane (does not need to be orthogonal or normalized).
  • sizehalf-width of the quad along the (processed) direction.

Return

std::array<Triangle<Vector3<float>>, 2> — the quad triangulated (consistent CCW winding, outward normal per e × width).


Robust construction (expected math)

  1. e = vertex_b - vertex_a

  2. Make d perpendicular to e:

    d = direction - e * (e.dot(direction) / e.length_sqr());
    if (d.length_sqr() == 0) pick an arbitrary perpendicular to e
    d = d.normalized();
    
  3. Offsets: w = d * size

  4. Four corners:

    A0 = vertex_a - w;  A1 = vertex_a + w;
    B0 = vertex_b - w;  B1 = vertex_b + w;
    
  5. Triangles (CCW when viewed from +normal):

    T0 = Triangle{ A0, A1, B1 }
    T1 = Triangle{ A0, B1, B0 }
    

Example

using omath::Vector3;
using omath::Triangle;
using omath::primitives::create_plane;

Vector3<float> a{ -1, 0, -1 };    // edge start
Vector3<float> b{  1, 0, -1 };    // edge end
Vector3<float> dir{ 0, 0, 1 };    // cross-edge direction within the plane (roughly +Z)
float half_width = 2.0f;

auto quad = create_plane(a, b, dir, half_width);

// e.g., compute normals
for (const auto& tri : quad) {
  auto n = tri.calculate_normal(); (void)n;
}

Notes & edge cases

  • Degenerate edge: if vertex_a == vertex_b, the plane is undefined.
  • Collinearity: if direction is parallel to vertex_b - vertex_a, the function must choose an alternate perpendicular; expect a fallback.
  • Winding: If your renderer expects a specific face order, verify and swap the two vertices in each triangle as needed.