106 lines
3.0 KiB
C++
106 lines
3.0 KiB
C++
#pragma once
|
||
#include "vde/core/point.h"
|
||
#include "vde/curves/bspline_curve.h"
|
||
#include <vector>
|
||
|
||
namespace vde::curves {
|
||
using core::Point3D;
|
||
using core::Vector3D;
|
||
|
||
/**
|
||
* @brief B 样条张量积曲面(非有理)
|
||
*
|
||
* 由 (nu+1)×(nv+1) 控制点网格、u/v 向各一个节点向量以及两个阶次定义。
|
||
* 参数域 (u,v) ∈ [knots_u[pu], knots_u[nu+1]] × [knots_v[pv], knots_v[nv+1]]。
|
||
*
|
||
* 求值公式:S(u,v) = Σ_i Σ_j P_{ij} · N_{i,pu}(u) · N_{j,pv}(v)
|
||
*
|
||
* 具有局部控制性:修改单个控制点仅影响相邻 pu×pv 个节点区间的曲面区域。
|
||
*
|
||
* @ingroup curves
|
||
*/
|
||
class BSplineSurface {
|
||
public:
|
||
/**
|
||
* @brief 构造 B 样条曲面
|
||
* @param control_grid (nu+1)×(nv+1) 控制点网格
|
||
* @param knots_u u 向节点向量,长度 = nu + pu + 1
|
||
* @param knots_v v 向节点向量,长度 = nv + pv + 1
|
||
* @param degree_u u 向阶次 pu
|
||
* @param degree_v v 向阶次 pv
|
||
* @code{.cpp}
|
||
* BSplineSurface surf(grid,
|
||
* {0,0,0,0, 0.5, 1,1,1,1}, // u knots (三次,5 个控制点)
|
||
* {0,0,0, 0.5, 1,1,1}, // v knots (二次,4 个控制点)
|
||
* 3, 2);
|
||
* @endcode
|
||
*/
|
||
BSplineSurface(std::vector<std::vector<Point3D>> control_grid,
|
||
std::vector<double> knots_u, std::vector<double> knots_v,
|
||
int degree_u, int degree_v);
|
||
|
||
/**
|
||
* @brief 求曲面点 S(u,v)
|
||
* @param u u 参数
|
||
* @param v v 参数
|
||
* @return 曲面上的 3D 点
|
||
* @note 张量积分解:先行后列(或先列后行)做两次 B 样条求值
|
||
*/
|
||
[[nodiscard]] Point3D evaluate(double u, double v) const;
|
||
|
||
/**
|
||
* @brief u 向偏导数 ∂S/∂u
|
||
* @param u u 参数
|
||
* @param v v 参数
|
||
* @return 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 单位法向量
|
||
* @param u u 参数
|
||
* @param v v 参数
|
||
* @return N(u,v) = (∂S/∂u × ∂S/∂v) / |…|
|
||
*/
|
||
[[nodiscard]] Vector3D normal(double u, double v) const;
|
||
|
||
/**
|
||
* @brief u 向阶次
|
||
* @return pu
|
||
*/
|
||
[[nodiscard]] int degree_u() const { return degree_u_; }
|
||
|
||
/**
|
||
* @brief v 向阶次
|
||
* @return pv
|
||
*/
|
||
[[nodiscard]] int degree_v() const { return degree_v_; }
|
||
|
||
/**
|
||
* @brief u 向节点向量
|
||
* @return 只读引用
|
||
*/
|
||
[[nodiscard]] const std::vector<double>& knots_u() const { return knots_u_; }
|
||
|
||
/**
|
||
* @brief v 向节点向量
|
||
* @return 只读引用
|
||
*/
|
||
[[nodiscard]] const std::vector<double>& knots_v() const { return knots_v_; }
|
||
|
||
private:
|
||
std::vector<std::vector<Point3D>> cp_; ///< 控制点网格
|
||
std::vector<double> knots_u_, knots_v_; ///< u/v 向节点向量
|
||
int degree_u_, degree_v_; ///< u/v 向阶次
|
||
};
|
||
|
||
} // namespace vde::curves
|