Files
ViewDesignEngine/include/vde/curves/bezier_surface.h
T

92 lines
2.8 KiB
C++
Raw Normal View History

#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