增加了QPainterPath的单调化
parent
ef88c4a39e
commit
315083cd52
|
@ -127,7 +127,6 @@
|
||||||
<ClCompile Include="src\Renderer\Camera.cpp" />
|
<ClCompile Include="src\Renderer\Camera.cpp" />
|
||||||
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp" />
|
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp" />
|
||||||
<ClCompile Include="src\Renderer\Painting\CubicBezierSignedDistance.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\Light.cpp" />
|
||||||
<ClCompile Include="src\Renderer\Painting\Element.cpp" />
|
<ClCompile Include="src\Renderer\Painting\Element.cpp" />
|
||||||
<ClCompile Include="src\Renderer\Painting\ElementStyle.cpp" />
|
<ClCompile Include="src\Renderer\Painting\ElementStyle.cpp" />
|
||||||
|
@ -215,7 +214,6 @@
|
||||||
<ClInclude Include="src\Renderer\Painting\BvhTree.h" />
|
<ClInclude Include="src\Renderer\Painting\BvhTree.h" />
|
||||||
<ClInclude Include="src\Renderer\Camera.h" />
|
<ClInclude Include="src\Renderer\Camera.h" />
|
||||||
<ClInclude Include="src\Renderer\Painting\CubicBezier.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\Drawable.h" />
|
||||||
<ClInclude Include="src\Renderer\Light.h" />
|
<ClInclude Include="src\Renderer\Light.h" />
|
||||||
<ClInclude Include="src\Renderer\Painting\Line.h" />
|
<ClInclude Include="src\Renderer\Painting\Line.h" />
|
||||||
|
|
|
@ -129,9 +129,6 @@
|
||||||
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp">
|
<ClCompile Include="src\Renderer\Painting\CubicBezier.cpp">
|
||||||
<Filter>Source Files\Renderer\Painting</Filter>
|
<Filter>Source Files\Renderer\Painting</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\Renderer\Painting\CubicMonotonization.cpp">
|
|
||||||
<Filter>Source Files\Renderer\Painting</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\Renderer\Painting\PaintingHelper.cpp">
|
<ClCompile Include="src\Renderer\Painting\PaintingHelper.cpp">
|
||||||
<Filter>Source Files\Renderer\Painting</Filter>
|
<Filter>Source Files\Renderer\Painting</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -360,9 +357,6 @@
|
||||||
<ClInclude Include="src\Renderer\Painting\CubicBezier.h">
|
<ClInclude Include="src\Renderer\Painting\CubicBezier.h">
|
||||||
<Filter>Header Files\Renderer\Painting</Filter>
|
<Filter>Header Files\Renderer\Painting</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="src\Renderer\Painting\CubicMonotonization.h">
|
|
||||||
<Filter>Header Files\Renderer\Painting</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="src\Renderer\Painting\Line.h">
|
<ClInclude Include="src\Renderer\Painting\Line.h">
|
||||||
<Filter>Header Files\Renderer\Painting</Filter>
|
<Filter>Header Files\Renderer\Painting</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include "PainterPathUtil.h"
|
#include "PainterPathUtil.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "../../Renderer/Painting/LineTree.h"
|
||||||
|
|
||||||
using Renderer::Point;
|
using Renderer::Point;
|
||||||
|
using Renderer::Line;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::shared_ptr;
|
||||||
|
|
||||||
vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterPath) {
|
vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterPath) {
|
||||||
vector<Point> line; line.clear();
|
vector<Point> line; line.clear();
|
||||||
|
@ -39,3 +42,22 @@ vector<vector<Point> > PainterPathUtil::transformToLines(QPainterPath& painterP
|
||||||
line.clear();
|
line.clear();
|
||||||
return lines;
|
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:
|
public:
|
||||||
static std::vector<std::vector<Point> > transformToLines(QPainterPath& painterPath);
|
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() {
|
operator glm::dvec2() {
|
||||||
return glm::dvec2(x, y);
|
return glm::dvec2(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator QPointF() {
|
||||||
|
return QPointF(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void show() {
|
void show() {
|
||||||
std::cout << '(' << x << ',' << y << ')' << ' ';
|
std::cout << '(' << x << ',' << y << ')' << ' ';
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,13 @@ namespace Renderer {
|
||||||
bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
|
bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
|
||||||
static bool IsBorderValueResonable(double value, std::set <double>& valueSet);
|
static bool IsBorderValueResonable(double value, std::set <double>& valueSet);
|
||||||
static double findBorderValueNotOnLine(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:
|
public:
|
||||||
void init();
|
void init();
|
||||||
void setLineWidth(double width);
|
void setLineWidth(double width);
|
||||||
LineTree(int lineMin = 3)
|
LineTree(int lineMin = 3)
|
||||||
: requiredLineMin(lineMin), numLine(0), numPoint(0) {}
|
: requiredLineMin(lineMin), numLine(0), numPoint(0) {}
|
||||||
void buildLineTree(std::vector<PointVector>& lineSet, double width, int type = 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);
|
std::vector<BvhTreeData> getPointLineAndBvhTree(std::vector<float>& pointSet, std::vector<GLuint>& lineSet);
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue