增加了QPainterPath的单调化
parent
ef88c4a39e
commit
315083cd52
|
@ -127,7 +127,6 @@
|
|||
<ClCompile Include="src\Renderer\Camera.cpp" />
|
||||
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp" />
|
||||
<ClCompile Include="src\Renderer\Painting\CubicBezierSignedDistance.cpp" />
|
||||
<ClCompile Include="src\Renderer\Painting\CubicMonotonization.cpp" />
|
||||
<ClCompile Include="src\Renderer\Light.cpp" />
|
||||
<ClCompile Include="src\Renderer\Painting\Element.cpp" />
|
||||
<ClCompile Include="src\Renderer\Painting\ElementStyle.cpp" />
|
||||
|
@ -215,7 +214,6 @@
|
|||
<ClInclude Include="src\Renderer\Painting\BvhTree.h" />
|
||||
<ClInclude Include="src\Renderer\Camera.h" />
|
||||
<ClInclude Include="src\Renderer\Painting\CubicBezier.h" />
|
||||
<ClInclude Include="src\Renderer\Painting\CubicMonotonization.h" />
|
||||
<ClInclude Include="src\Renderer\Drawable.h" />
|
||||
<ClInclude Include="src\Renderer\Light.h" />
|
||||
<ClInclude Include="src\Renderer\Painting\Line.h" />
|
||||
|
|
|
@ -129,9 +129,6 @@
|
|||
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp">
|
||||
<Filter>Source Files\Renderer\Painting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Renderer\Painting\CubicMonotonization.cpp">
|
||||
<Filter>Source Files\Renderer\Painting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Renderer\Painting\PaintingHelper.cpp">
|
||||
<Filter>Source Files\Renderer\Painting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -360,9 +357,6 @@
|
|||
<ClInclude Include="src\Renderer\Painting\CubicBezier.h">
|
||||
<Filter>Header Files\Renderer\Painting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Renderer\Painting\CubicMonotonization.h">
|
||||
<Filter>Header Files\Renderer\Painting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Renderer\Painting\Line.h">
|
||||
<Filter>Header Files\Renderer\Painting</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "PainterPathUtil.h"
|
||||
#include <QDebug>
|
||||
#include "../../Renderer/Painting/LineTree.h"
|
||||
|
||||
using Renderer::Point;
|
||||
using Renderer::Line;
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
|
||||
vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterPath) {
|
||||
vector<Point> line; line.clear();
|
||||
|
@ -39,3 +42,22 @@ vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterP
|
|||
line.clear();
|
||||
return lines;
|
||||
}
|
||||
|
||||
QPainterPath PainterPathUtil::monotonization(QPainterPath& painterPath) {
|
||||
QPainterPath resPath;
|
||||
vector<vector<Point> > lines = transformToLines(painterPath);
|
||||
vector<shared_ptr<Line>> linePtrVector;
|
||||
Renderer::LineTree::monotonization(lines, linePtrVector);
|
||||
for (auto linePtr : linePtrVector) {
|
||||
vector<Point> line = linePtr->toPointVector();
|
||||
if (line.size() == 2) {
|
||||
resPath.moveTo(line[0]);
|
||||
resPath.lineTo(line[1]);
|
||||
}
|
||||
if (line.size() == 4) {
|
||||
resPath.moveTo(line[0]);
|
||||
resPath.cubicTo(line[1], line[2], line[3]);
|
||||
}
|
||||
}
|
||||
return resPath;
|
||||
}
|
||||
|
|
|
@ -9,5 +9,6 @@ class PainterPathUtil
|
|||
{
|
||||
public:
|
||||
static std::vector<std::vector<Point> > transformToLines(QPainterPath& painterPath);
|
||||
static QPainterPath monotonization(QPainterPath& painterPath);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
#include "CubicMonotonization.h"
|
||||
using namespace Renderer;
|
||||
using std::vector;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::sort;
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
class CubicMonotonization
|
||||
{
|
||||
typedef std::pair<double, double> point;
|
||||
typedef std::vector<point> Line;
|
||||
private:
|
||||
static const double eps;
|
||||
point getPointByT(point a, point b, double t) const;
|
||||
void findPointsOfDivison(std::vector<double> p, std::vector<double>& res);
|
||||
double getBezierPoint(std::vector<double>& p, double t) const;
|
||||
void splitBezierCubic(Line& p, point mid, double t, std::vector <Line>& res);
|
||||
public:
|
||||
// p 为端点、控制点、控制点、端点, res 为所有导数为0的点
|
||||
void getPointsOfDivision(Line p, std::vector <Line>& res);
|
||||
};
|
||||
|
||||
}
|
|
@ -33,6 +33,11 @@ namespace Renderer
|
|||
operator glm::dvec2() {
|
||||
return glm::dvec2(x, y);
|
||||
}
|
||||
|
||||
operator QPointF() {
|
||||
return QPointF(x, y);
|
||||
}
|
||||
|
||||
void show() {
|
||||
std::cout << '(' << x << ',' << y << ')' << ' ';
|
||||
}
|
||||
|
|
|
@ -41,13 +41,13 @@ namespace Renderer {
|
|||
bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
|
||||
static bool IsBorderValueResonable(double value, std::set <double>& valueSet);
|
||||
static double findBorderValueNotOnLine(double value, std::set <double>& valueSet);
|
||||
static void monotonization(std::vector<PointVector>& inL, std::vector<std::shared_ptr<Line>>& outL);
|
||||
public:
|
||||
void init();
|
||||
void setLineWidth(double width);
|
||||
LineTree(int lineMin = 3)
|
||||
: requiredLineMin(lineMin), numLine(0), numPoint(0) {}
|
||||
void buildLineTree(std::vector<PointVector>& lineSet, double width, int type = 0);
|
||||
static void monotonization(std::vector<PointVector>& inL, std::vector<std::shared_ptr<Line>>& outL);
|
||||
std::vector<BvhTreeData> getPointLineAndBvhTree(std::vector<float>& pointSet, std::vector<GLuint>& lineSet);
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue