Files
ViewDesignEngine/include/vde/curves/nurbs_curve.h
T
茂之钳 00ea90b522
CI / Build & Test (push) Failing after 38s
CI / Release Build (push) Failing after 41s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
fix: add default constructors to NurbsCurve and NurbsSurface
2026-07-24 14:26:47 +00:00

102 lines
3.1 KiB
C++
Raw 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 "vde/curves/bspline_curve.h"
#include <vector>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
/**
* @brief NURBS 曲线(Non-Uniform Rational B-Spline
*
* B 样条的有理推广,引入权重 w_i 使每个控制点的影响可调。
* 通过投影变换将齐次坐标中的 B 样条映射到 3D 空间。
*
* 求值公式:C(t) = Σ N_{i,p}(t) · w_i · P_i / Σ N_{i,p}(t) · w_i
*
* 关键性质:
* - 可精确表示圆锥曲线(圆、椭圆)——Bézier/B 样条无法做到
* - 权重 w_i 越大,曲线越靠近控制点 P_i
* - 所有权重 = 1 时退化为 B 样条
* - 所有权重 > 0 时在凸包内
*
* @ingroup curves
*/
class NurbsCurve {
public:
/**
* @brief 构造 NURBS 曲线
* @param control_points 控制点序列
* @param knots 节点向量
* @param weights 权重序列,必须与 control_points 等长,各分量 > 0
* @param degree 阶次 p
* @note 所有权重必须 > 0 以保证分母不为零(非退化)
* @code{.cpp}
* // 用 NURBS 表示四分之一圆(7 个控制点,三次)
* NurbsCurve arc(cps, {0,0,0,0, 0.5, 1,1,1,1},
* {1, sqrt2/2, 1, sqrt2/2, 1, sqrt2/2, 1}, 3);
* @endcode
*/
NurbsCurve() : degree_(0) {} // degenerate empty curve
NurbsCurve(std::vector<Point3D> control_points, std::vector<double> knots,
std::vector<double> weights, int degree);
/**
* @brief 在参数 t 处求值
* @param t 参数值
* @return 曲线上对应 t 的点坐标
* @note 内部将 (w·P, w) 提升为齐次坐标的 B 样条,求值后投影回 3D
*/
[[nodiscard]] Point3D evaluate(double t) const;
/**
* @brief 在参数 t 处求导数
* @param t 参数值
* @param order 导数阶数
* @return 导数向量
* @note 有理导数公式:
* C^{(k)} = (A^{(k)} - Σ_{j=1}^{k} C(k,j) · w^{(j)} · C^{(k-j)}) / w
* 其中 A(t) = Σ N_i(t)·w_i·P_iw(t) = Σ N_i(t)·w_i
*/
[[nodiscard]] Vector3D derivative(double t, int order = 1) const;
/**
* @brief 曲线阶次
* @return p
*/
[[nodiscard]] int degree() const { return degree_; }
/**
* @brief 参数定义域
* @return [knots[degree], knots[n+1]]
*/
[[nodiscard]] std::pair<double, double> domain() const;
/**
* @brief 控制点访问
* @return 只读引用
*/
[[nodiscard]] const std::vector<Point3D>& control_points() const { return cp_; }
/**
* @brief 权重访问
* @return 只读引用
*/
[[nodiscard]] const std::vector<double>& weights() const { return weights_; }
/**
* @brief 节点向量访问
* @return 只读引用
*/
[[nodiscard]] const std::vector<double>& knots() const { return knots_; }
private:
std::vector<Point3D> cp_; ///< 控制点
std::vector<double> knots_; ///< 节点向量
std::vector<double> weights_; ///< 权重,w_i > 0
int degree_; ///< 阶次
};
} // namespace vde::curves