92 lines
2.8 KiB
C++
92 lines
2.8 KiB
C++
#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_u,n = 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
|