game-spatial-queries

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Game Spatial Queries

游戏空间查询

Use this skill to turn game picking, collision, containment, and distance questions into small geometric systems with explicit constraints and failure cases.
Primary source: Geometry for Programmers by Oleksandr Kaleniuk (https://www.manning.com/books/geometry-for-programmers), transformed and paraphrased, especially chapters 3, 4, and 9. Additional source: "Fast, Minimum Storage Ray-Triangle Intersection" by Tomas Moller and Ben Trumbore (https://dl.acm.org/doi/10.1145/1198555.1198746).
使用本技能可将游戏中的拾取(picking)、碰撞、包含性及距离问题转化为具有明确约束和失败场景的小型几何系统。
主要参考资料:Oleksandr Kaleniuk 所著的《Geometry for Programmers》(https://www.manning.com/books/geometry-for-programmers),内容经过改写和转述,尤其参考了第3、4、9章。补充资料:Tomas Moller 和 Ben Trumbore 发表的论文《Fast, Minimum Storage Ray-Triangle Intersection》(https://dl.acm.org/doi/10.1145/1198555.1198746)。

Core Workflow

核心工作流

  1. State the query as a predicate or measured value: hit/miss, inside/outside, closest distance, signed side, intersection point, or parameter value.
  2. Move into the simplest local basis when possible. Triangle, segment, plane, and object-local bases often reduce the query to bounds checks.
  3. Derive parameters first, then apply constraints. Keep constraints visible in code instead of burying them in one large expression.
  4. Identify denominator, orientation, or length values that signal degeneracy.
  5. Choose a numeric policy: exact integer predicate, scale-aware epsilon, inclusive boundary, exclusive boundary, or conservative fallback.
  6. Test hit, miss, boundary, parallel, degenerate, and near-degenerate cases.
  7. Add a debug visualization when the query affects gameplay feel.
  1. 将查询表述为谓词或可测量值:命中/未命中、内部/外部、最近距离、有符号方向、交点或参数值。
  2. 尽可能转换到最简单的局部坐标系。三角形、线段、平面以及物体局部坐标系通常可以将查询简化为边界检查。
  3. 先推导参数,再应用约束。让约束在代码中清晰可见,不要将其埋藏在一个庞大的表达式里。
  4. 识别表示退化情况的分母、方向或长度值。
  5. 选择数值处理策略:精确整数谓词、感知尺度的epsilon、包含边界、排除边界或保守回退方案。
  6. 测试命中、未命中、边界、平行、退化及近退化场景。
  7. 当查询会影响游戏手感时,添加调试可视化功能。

Query Patterns

查询模式

Ray Against Triangle

光线与三角形相交

Model the ray as
R = P + t*d
with
t >= 0
. Model triangle points as
S = A + u*AB + v*AC
with
u >= 0
,
v >= 0
, and
u + v <= 1
.
Solve
R = S
, then:
  • Reject when the shared denominator is zero or too small for the numeric policy.
  • Reject when
    t < 0
    .
  • Reject when
    u < 0
    ,
    v < 0
    , or
    u + v > 1
    .
  • Return hit distance
    t
    , barycentric-like parameters
    u
    and
    v
    , and the hit point when needed.
将光线建模为
R = P + t*d
,其中
t >= 0
。将三角形上的点建模为
S = A + u*AB + v*AC
,其中
u >= 0
、
v >= 0
且
u + v <= 1
。
求解
R = S
,然后:
  • 当公共分母为零或小于数值策略的阈值时,判定为未命中。
  • 当
    t < 0
    时,判定为未命中。
  • 当
    u < 0
    、
    v < 0
    或
    u + v > 1
    时,判定为未命中。
  • 返回命中距离
    t
    、类重心参数
    u
    和
    v
    ,以及需要时返回命中点。

Point In Triangle

点在三角形内检测

Prefer one of these approaches:
  • Transform the triangle to its local basis and check
    0 <= u
    ,
    0 <= v
    ,
    u + v <= 1
    .
  • Use consistent edge orientation signs from 2D cross products.
  • Use barycentric coordinates when the caller needs interpolation weights too.
Decide whether points on edges count as inside. Tests must cover both the chosen edge policy and reversed triangle winding.
优先选择以下方法之一:
  • 将三角形转换到其局部坐标系,检查
    0 <= u
    、
    0 <= v
    、
    u + v <= 1
    。
  • 使用2D叉乘得到的一致边方向符号。
  • 当调用方还需要插值权重时,使用重心坐标。
需要明确边上的点是否算作内部。测试必须同时覆盖所选的边界策略和反向的三角形绕序。

Signed Point To Plane

点到平面的有符号距离

Build a plane normal from two nonparallel edges. Dot the normalized normal with the vector from any plane point to the query point. Keep the sign when side matters; take absolute value only for unsigned distance.
用两条不平行的边构建平面法向量。将归一化后的法向量与平面上任意一点指向查询点的向量做点积。当需要区分方向时保留符号;仅在需要无符号距离时取绝对值。

Segment And Closest-Point Queries

线段与最近点查询

Project onto the segment direction, clamp the parameter to
[0, 1]
, then measure distance to the clamped point. Reject or special-case zero-length segments before normalization.
将点投影到线段方向上,将参数钳制到
[0, 1]
区间,然后计算到钳制后点的距离。在归一化之前,对零长度线段进行拒绝或特殊处理。

Degenerate Geometry Policy

退化几何处理策略

  • Zero-length vectors must not be normalized.
  • Degenerate triangles must not create unstable bases or normals.
  • Parallel ray/plane cases need a deliberate answer: no hit, coplanar handling, or fallback query.
  • Very small denominators need a scale-aware policy. A fixed epsilon is often wrong across different world scales.
  • Boundary inclusion must match gameplay: selection tools often want inclusive checks; collision separation often wants conservative checks.
  • 零长度向量不得进行归一化。
  • 退化三角形不得用于构建不稳定的基或法向量。
  • 光线与平面平行的场景需要有明确的处理结果:未命中、共面处理或回退查询。
  • 极小的分母需要感知尺度的处理策略。固定的epsilon在不同的世界尺度下通常是错误的。
  • 边界包含规则必须与游戏玩法匹配:选择工具通常需要包含性检查;碰撞分离通常需要保守检查。

Implementation Checklist

实现检查清单

  • Function name states geometry and boundary policy.
  • Inputs document coordinate space and units.
  • Winding assumptions are explicit.
  • Denominator and zero-length cases are handled before division.
  • Return type exposes enough detail for the caller: bool, distance, hit point, normal, barycentric weights, or rejection reason.
  • Tests include normal case, miss case, edge/vertex case, reversed winding, parallel case, degenerate case, and large/small scale case.
  • 函数名需体现几何类型和边界策略。
  • 输入参数需标注坐标空间和单位。
  • 绕序假设需明确说明。
  • 在做除法之前处理分母为零和零长度的情况。
  • 返回类型需为调用方提供足够的细节:布尔值、距离、命中点、法向量、重心权重或拒绝原因。
  • 测试需覆盖正常场景、未命中场景、边/顶点场景、反向绕序、平行场景、退化场景以及大/小尺度场景。

Common Mistakes

常见错误

  • Computing a global-space query when object-local coordinates make it trivial.
  • Returning only
    bool
    from a query that later needs hit distance or normal.
  • Comparing floats to zero with no policy.
  • Forgetting that normals and barycentric coordinates depend on winding.
  • Treating "not hit" and "invalid input geometry" as the same debugging signal.
  • 明明用物体局部坐标可以轻松解决的查询,却在全局空间中计算。
  • 查询仅返回
    bool
    值,但后续需要命中距离或法向量。
  • 没有明确策略就将浮点数与零进行比较。
  • 忘记法向量和重心坐标依赖于绕序。
  • 将「未命中」和「输入几何无效」视为同一种调试信号。