ViewDesignEngine  3.1.0
高性能 CAD 计算几何引擎
sdf_primitives.h
浏览该文件的文档.
1 #pragma once
27 #include "vde/core/point.h"
28 #include <cmath>
29 #include <algorithm>
30 
31 namespace vde::sdf {
32 using core::Point3D;
33 using core::Vector3D;
34 
35 // ═══════════════════════════════════════════════
36 // Basic Primitives
37 // ═══════════════════════════════════════════════
38 
68 [[nodiscard]] inline double sphere(const Point3D& p, double radius) {
69  return p.norm() - radius;
70 }
71 
96 [[nodiscard]] inline double box(const Point3D& p, const Point3D& half_extents) {
97  Point3D q = p.cwiseAbs() - half_extents;
98  return q.cwiseMax(0.0).norm()
99  + std::min(std::max({q.x(), q.y(), q.z()}), 0.0);
100 }
101 
126 [[nodiscard]] inline double round_box(const Point3D& p, const Point3D& half_extents, double r) {
127  Point3D q = p.cwiseAbs() - half_extents;
128  return q.cwiseMax(0.0).norm()
129  + std::min(std::max({q.x(), q.y(), q.z()}), 0.0)
130  - r;
131 }
132 
159 [[nodiscard]] inline double torus(const Point3D& p, double major_radius, double minor_radius) {
160  double qx = std::sqrt(p.x() * p.x() + p.z() * p.z()) - major_radius;
161  return std::sqrt(qx * qx + p.y() * p.y()) - minor_radius;
162 }
163 
189 [[nodiscard]] inline double capsule(const Point3D& p, const Point3D& a, const Point3D& b, double radius) {
190  Point3D pa = p - a;
191  Point3D ba = b - a;
192  double ba_sq = ba.squaredNorm();
193  if (ba_sq < 1e-30) {
194  // Degenerate to sphere
195  return pa.norm() - radius;
196  }
197  double h = std::clamp(pa.dot(ba) / ba_sq, 0.0, 1.0);
198  return (pa - ba * h).norm() - radius;
199 }
200 
227 [[nodiscard]] inline double cylinder(const Point3D& p, double radius, double height) {
228  double d_xz = std::sqrt(p.x() * p.x() + p.z() * p.z()) - radius;
229  double d_y = std::abs(p.y()) - height * 0.5;
230  return std::min(std::max(d_xz, d_y), 0.0)
231  + std::sqrt(std::max(d_xz, 0.0) * std::max(d_xz, 0.0)
232  + std::max(d_y, 0.0) * std::max(d_y, 0.0));
233 }
234 
261 [[nodiscard]] inline double plane(const Point3D& p, const Vector3D& normal, double offset) {
262  return p.dot(normal) - offset;
263 }
264 
294 [[nodiscard]] inline double ellipsoid(const Point3D& p, const Point3D& radii) {
295  Point3D pr(p.x() / radii.x(), p.y() / radii.y(), p.z() / radii.z());
296  double k0 = pr.norm();
297  double k1 = Point3D(p.x() / (radii.x() * radii.x()),
298  p.y() / (radii.y() * radii.y()),
299  p.z() / (radii.z() * radii.z())).norm();
300  if (k1 < 1e-30) {
301  // Degenerate: point at origin → distance = -min(radii)
302  return -std::min({radii.x(), radii.y(), radii.z()});
303  }
304  return k0 * (k0 - 1.0) / k1;
305 }
306 
307 // ═══════════════════════════════════════════════
308 // Parametric Primitives
309 // ═══════════════════════════════════════════════
310 
333 [[nodiscard]] inline double hex_prism(const Point3D& p, double radius, double height) {
334  double px = std::abs(p.x());
335  double pz = std::abs(p.z());
336  // 2D hexagon SDF (pointy-top in XZ plane)
337  double d_hex = std::max(px + pz * 0.577350269189626, pz * 1.154700538379252) - radius;
338  // Extrude along Y
339  return std::max(d_hex, std::abs(p.y()) - height * 0.5);
340 }
341 
365 [[nodiscard]] inline double infinite_cylinder(const Point3D& p, const Vector3D& axis, double radius) {
366  return p.cross(axis).norm() - radius;
367 }
368 
393 [[nodiscard]] inline double wedge(const Point3D& p, double w, double h, double d) {
394  Point3D q = p.cwiseAbs() - Point3D(w * 0.5, h * 0.5, d * 0.5);
395  double d_box = q.cwiseMax(0.0).norm()
396  + std::min(std::max({q.x(), q.y(), q.z()}), 0.0);
397  // Diagonal plane x - z ≤ 0 (i.e., z ≥ x)
398  double d_cut = (p.x() - p.z()) * 0.707106781186548; // 1/√2
399  return std::max(d_box, d_cut);
400 }
401 
402 // ═══════════════════════════════════════════════
403 // 2D Extrusions & Revolution
404 // ═══════════════════════════════════════════════
405 
428 [[nodiscard]] inline double extrusion(const Point3D& /*p*/, double sdf_2d) {
429  return sdf_2d;
430 }
431 
452 [[nodiscard]] inline double extrusion_bounded(const Point3D& p, double sdf_2d, double half_height) {
453  return std::max(sdf_2d, std::abs(p.z()) - half_height);
454 }
455 
479 [[nodiscard]] inline double revolution(const Point3D& /*p*/, double sdf_2d, double /*offset*/) {
480  return sdf_2d;
481 }
482 
483 // ═══════════════════════════════════════════════
484 // Complex Primitives (implemented in src/sdf/)
485 // ═══════════════════════════════════════════════
486 
507 [[nodiscard]] double cone(const Point3D& p, double angle_rad, double height);
508 
530 [[nodiscard]] double triangular_prism(const Point3D& p, const Point3D& a, const Point3D& b,
531  const Point3D& c, double height);
532 
552 [[nodiscard]] double link(const Point3D& p, double length, double major_r, double minor_r);
553 
575 [[nodiscard]] double infinite_cone(const Point3D& p, const Point3D& apex,
576  const Vector3D& axis, double angle_rad);
577 
578 } // namespace vde::sdf
foundation::Vector3D Vector3D
双精度三维向量(重新导出)
Definition: point.h:49
foundation::Point3D Point3D
双精度三维点(重新导出)
Definition: point.h:31
double link(const Point3D &p, double length, double major_r, double minor_r)
双环链接体的 SDF(非内联实现)
double cone(const Point3D &p, double angle_rad, double height)
圆锥台的 SDF(非内联实现)
double infinite_cylinder(const Point3D &p, const Vector3D &axis, double radius)
无限长圆柱的 SDF
double ellipsoid(const Point3D &p, const Point3D &radii)
椭球体的 SDF(有界梯度近似)
double hex_prism(const Point3D &p, double radius, double height)
正六棱柱的 SDF
double extrusion(const Point3D &, double sdf_2d)
二维 SDF 沿 Z 轴的无限挤出
double capsule(const Point3D &p, const Point3D &a, const Point3D &b, double radius)
胶囊体的 SDF
double triangular_prism(const Point3D &p, const Point3D &a, const Point3D &b, const Point3D &c, double height)
三角棱柱的 SDF(非内联实现)
double box(const Point3D &p, const Point3D &half_extents)
轴对齐立方体的 SDF
double infinite_cone(const Point3D &p, const Point3D &apex, const Vector3D &axis, double angle_rad)
无限圆锥的 SDF(非内联实现)
double cylinder(const Point3D &p, double radius, double height)
带平端盖的圆柱体 SDF
double torus(const Point3D &p, double major_radius, double minor_radius)
圆环面的 SDF
double round_box(const Point3D &p, const Point3D &half_extents, double r)
圆角立方体的 SDF
double revolution(const Point3D &, double sdf_2d, double)
二维轮廓绕 Y 轴的旋转体 SDF
double wedge(const Point3D &p, double w, double h, double d)
楔形体的 SDF
double extrusion_bounded(const Point3D &p, double sdf_2d, double half_height)
二维 SDF 的有限长度挤出
double sphere(const Point3D &p, double radius)
球体的 SDF
double plane(const Point3D &p, const Vector3D &normal, double offset)
平面的 SDF