增加了分割的贝塞尔曲线的控制点

dev-VirtualTexture
yang.yongquan 2022-09-13 21:01:18 +08:00
parent 081e9a7ffb
commit 79883302ac
4 changed files with 105 additions and 0 deletions

View File

@ -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" />

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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);
};