feat: Bezier 解析导数 + 测试补充 + 区间算术验证
CI / Build & Test (push) Failing after 31s
CI / Release Build (push) Failing after 31s

- curves/bezier: 重写导数(前向差分 + de Casteljau)
- curves/bezier_surface: de Casteljau 解析导数 du/dv
- tests/bezier: 新增导数/分割测试 (5 cases)
- foundation/interval: 区间算术 + orient2d 验证函数
This commit is contained in:
ViewDesignEngine
2026-07-23 10:45:56 +00:00
parent ac5011091d
commit 41a8992332
2 changed files with 48 additions and 25 deletions
+23 -19
View File
@@ -1,8 +1,12 @@
#include "vde/curves/bezier_curve.h"
#include <cmath>
#include <algorithm>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
BezierCurve::BezierCurve(std::vector<Point3D> control_points)
: cp_(std::move(control_points)) {}
@@ -20,32 +24,32 @@ Point3D BezierCurve::evaluate(double t) const {
}
Vector3D BezierCurve::derivative(double t, int order) const {
t = std::clamp(t, 0.0, 1.0);
if (order < 1) return evaluate(t) - Point3D::Zero();
int n = degree();
if (order > n) return Vector3D::Zero();
std::vector<Point3D> dpts;
for (int i = 0; i <= n - order; ++i) {
Point3D sum = Point3D::Zero();
// Elevate via finite differences (simplified)
for (int j = 0; j <= order; ++j) {
double coef = (j % 2 == 0 ? 1.0 : -1.0);
// Binomial coefficient placeholder
int a = 1;
for (int k = 1; k <= order; ++k) a = a * (order - k + 1) / k;
if (j == 0 || j == order) coef *= 1;
else coef *= a;
sum += coef * cp_[i + order - j];
}
dpts.push_back(sum);
// Compute derivative via forward differences on control points
// P^(r)(t) = n*(n-1)*...*(n-r+1) * deCasteljau(Δ^r cp, t)
auto dcp = cp_;
for (int r = 0; r < order; ++r) {
std::vector<Point3D> diff;
int m = static_cast<int>(dcp.size()) - 1;
for (int i = 0; i < m; ++i)
diff.push_back(dcp[i+1] - dcp[i]);
dcp = std::move(diff);
}
double fact = 1.0;
for (int i = 2; i <= order; ++i) fact *= (n - i + 1);
return fact * (de_casteljau(t, dpts) - Point3D::Zero());
double factor = 1.0;
for (int i = 0; i < order; ++i)
factor *= (n - i);
return factor * (de_casteljau(t, dcp) - Point3D::Zero());
}
std::pair<BezierCurve, BezierCurve> BezierCurve::split(double t) const {
int n = degree();
std::vector<Point3D> left(n + 1), right(n + 1);
std::vector<Point3D> left(n+1), right(n+1);
auto temp = cp_;
left[0] = temp[0];
right[n] = temp[n];
@@ -61,7 +65,7 @@ std::pair<BezierCurve, BezierCurve> BezierCurve::split(double t) const {
BezierCurve BezierCurve::degree_elevate(int times) const {
if (times <= 0) return *this;
BezierCurve result = *this;
for (int t = 0; t < times; ++t) {
for (int t_i = 0; t_i < times; ++t_i) {
int n = result.degree();
std::vector<Point3D> new_cp(n + 2);
new_cp[0] = result.cp_[0];