增加了分割的贝塞尔曲线的控制点
parent
081e9a7ffb
commit
79883302ac
|
@ -87,6 +87,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="BvhTree.cpp" />
|
||||
<ClCompile Include="Camera.cpp" />
|
||||
<ClCompile Include="CubicMonotonization.cpp" />
|
||||
<ClCompile Include="Light.cpp" />
|
||||
<ClCompile Include="Mesh.cpp" />
|
||||
<ClCompile Include="Model.cpp" />
|
||||
|
@ -123,6 +124,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="BvhTree.h" />
|
||||
<ClInclude Include="Camera.h" />
|
||||
<ClInclude Include="CubicMonotonization.h" />
|
||||
<ClInclude Include="Drawable.h" />
|
||||
<ClInclude Include="Light.h" />
|
||||
<ClInclude Include="Mesh.h" />
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
<ClCompile Include="Light.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CubicMonotonization.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="RendererWidget.h">
|
||||
|
@ -148,5 +151,8 @@
|
|||
<ClInclude Include="Light.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CubicMonotonization.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,73 @@
|
|||
#include "CubicMonotonization.h"
|
||||
|
||||
const double CubicMonotonization::eps = 1e-6;
|
||||
|
||||
|
||||
CubicMonotonization::point CubicMonotonization::getPointByT(point a, point b, double t) const {
|
||||
return { a.first * (1 - t) + b.first, a.second * (1 - t) + b.second };
|
||||
}
|
||||
|
||||
|
||||
void CubicMonotonization::findPointsOfDivison(vector<double> p, vector<double>& res) {
|
||||
double a = -p[0] + 7 * p[1] - 9 * p[2] + 3 * p[3];
|
||||
double b = 6 * p[0] - 12 * p[1] + 6 * p[2];
|
||||
double c = -3 * p[0] + 3*p[1];
|
||||
double deta = b * b - 4*a*c;
|
||||
if (fabs(deta) < eps) return;
|
||||
double t = 0;
|
||||
if (fabs(a) <= eps) {
|
||||
deta = sqrt(deta);
|
||||
t = -b + deta;
|
||||
if (0 < t && t < 1) {
|
||||
res.push_back(t);
|
||||
}
|
||||
if (fabs(deta) <= eps) return ;
|
||||
t = -b - deta;
|
||||
if (0 < t && t < 1) {
|
||||
res.push_back(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double CubicMonotonization::getBezierPoint(vector<double> &p, double t) const{
|
||||
double pt = 1 - t;
|
||||
return pt * pt * pt * p[0] + 3 * t * pt * pt * p[1] + 3 * t * t * pt * p[2] + t * t * t * p[3];
|
||||
}
|
||||
|
||||
void CubicMonotonization::splitBezierCubic(Line& p, point mid, double t, vector <Line>& res) {
|
||||
Line Lf; Lf.clear();
|
||||
double pt = 1 - t;
|
||||
Lf.push_back(p[0]);
|
||||
point pointF = getPointByT(p[0], p[1], t);
|
||||
point pointG = getPointByT(p[1], p[2], t);
|
||||
point pointH = getPointByT(p[2], p[3], t);
|
||||
Lf.push_back(pointF);
|
||||
Lf.push_back(getPointByT(pointF, pointG, t));
|
||||
Lf.push_back(mid);
|
||||
res.push_back(Lf);
|
||||
p[0] = mid;
|
||||
p[1] = getPointByT(pointG, pointH, t);
|
||||
p[2] = pointH;
|
||||
}
|
||||
|
||||
void CubicMonotonization::getPointsOfDivision(Line p, vector <Line>& res) {
|
||||
vector<double> vX, vY, re;
|
||||
vX.clear();
|
||||
vY.clear();
|
||||
re.clear();
|
||||
for (point now : p) {
|
||||
vX.push_back(now.first);
|
||||
vY.push_back(now.second);
|
||||
}
|
||||
findPointsOfDivison(vX, re);
|
||||
findPointsOfDivison(vY, re);
|
||||
sort(re.begin(), re.end());
|
||||
double lt = 0, x = 0, y = 0;
|
||||
for (double &t : re) {
|
||||
if (fabs(t - lt) <= eps) continue;
|
||||
x = getBezierPoint(vX, t);
|
||||
y = getBezierPoint(vY, t);
|
||||
splitBezierCubic(p, { x, y }, t, res);
|
||||
lt = t;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#pragma once
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::sort;
|
||||
class CubicMonotonization
|
||||
{
|
||||
typedef pair<double, double> point;
|
||||
typedef vector<point> Line;
|
||||
private:
|
||||
static const double eps;
|
||||
point getPointByT(point a, point b, double t) const;
|
||||
void findPointsOfDivison(vector<double> p, vector<double> &res);
|
||||
double getBezierPoint(vector<double> &p, double t) const;
|
||||
void splitBezierCubic(Line& p, point mid, double t, vector <Line> &res);
|
||||
public:
|
||||
// p 为端点、控制点、控制点、端点, res 为所有导数为0的点
|
||||
void getPointsOfDivision(Line p, vector <Line> &res);
|
||||
};
|
||||
|
Loading…
Reference in New Issue