Files
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

92 lines
2.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/core/point.h"
#include <vector>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
/**
* @brief Bézier 张量积曲面
*
* 由 (m+1)×(n+1) 控制点网格定义,m = degree_un = degree_v。
* 参数域 (u,v) ∈ [0,1]×[0,1],四个角点插值网格四角。
*
* 求值公式:S(u,v) = Σ_i Σ_j P_{ij} · B_i^m(u) · B_j^n(v)
*
* @ingroup curves
*/
class BezierSurface {
public:
/**
* @brief 构造 Bézier 曲面
* @param control_grid 控制点网格,grid[i][j] 对应 u 方向第 i 个、v 方向第 j 个控制点
* @note grid 必须矩整(所有行等长);grid.size() = degree_u+1, grid[0].size() = degree_v+1
* @code{.cpp}
* // 3x3 控制网格 → 双二次 Bézier 曲面
* BezierSurface surf({{p00,p01,p02}, {p10,p11,p12}, {p20,p21,p22}});
* @endcode
*/
BezierSurface(std::vector<std::vector<Point3D>> control_grid);
/**
* @brief 求曲面点 S(u,v)
* @param u u 参数,范围 [0, 1]
* @param v v 参数,范围 [0, 1]
* @return 曲面上对应 (u,v) 的 3D 坐标
* @note 张量积求值:先按 v 方向对每行做 de Casteljau,再沿 u 方向对结果做一次
*/
[[nodiscard]] Point3D evaluate(double u, double v) const;
/**
* @brief u 方向偏导数 ∂S/∂u
* @param u u 参数
* @param v v 参数
* @return u 方向切向量
* @note 通过降阶 Bézier 曲线计算:对 v 求值后沿 u 求导
*/
[[nodiscard]] Vector3D derivative_u(double u, double v) const;
/**
* @brief v 方向偏导数 ∂S/∂v
* @param u u 参数
* @param v v 参数
* @return v 方向切向量
*/
[[nodiscard]] Vector3D derivative_v(double u, double v) const;
/**
* @brief 单位法向量 N(u,v) = (∂S/∂u × ∂S/∂v) / |…|
* @param u u 参数
* @param v v 参数
* @return 归一化法向量(指向曲面的特选侧)
* @note 当两个偏导数平行时返回零向量(奇异点)
*/
[[nodiscard]] Vector3D normal(double u, double v) const;
/**
* @brief u 向阶次
* @return u 方向阶次(控制点行数 - 1)
*/
[[nodiscard]] int degree_u() const { return static_cast<int>(cp_.size()) - 1; }
/**
* @brief v 向阶次
* @return v 方向阶次(控制点列数 - 1)
*/
[[nodiscard]] int degree_v() const { return static_cast<int>(cp_[0].size()) - 1; }
private:
std::vector<std::vector<Point3D>> cp_; ///< 控制点网格 [u_idx][v_idx]
/**
* @brief 一维 de Casteljau 求值(内部辅助)
* @param t 参数
* @param pts 一维控制点序列
* @return 求值结果
*/
[[nodiscard]] Point3D de_casteljau(double t, const std::vector<Point3D>& pts) const;
};
} // namespace vde::curves