|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include "tgeometry.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <set></set>
|
|
Toshihiro Shimizu |
890ddd |
#include <map></map>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tstrokeoutline.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurveutil.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "drawutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
#include <crtdbg.h></crtdbg.h>
|
|
|
e280ae |
#include <windows.h></windows.h>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tsweepboundary.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Some using declaration
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool operator<(const TPointD &a, const TPointD &b) {
|
|
Shinya Kitaoka |
120a6e |
if (a.x < b.x)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
else if (a.x > b.x)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else if (a.y < b.y)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
else if (a.y > b.y)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
const double delta = 0.000001;
|
|
Shinya Kitaoka |
120a6e |
const double zero = delta;
|
|
Shinya Kitaoka |
120a6e |
const double one = 1 - delta;
|
|
Shinya Kitaoka |
120a6e |
const double thicknessLimit = 0.3;
|
|
Toshihiro Shimizu |
890ddd |
const double nonSimpleLoopsMaxDistance = 0.5;
|
|
Shinya Kitaoka |
120a6e |
const int nonSimpleLoopsMaxSize = 5;
|
|
Shinya Kitaoka |
120a6e |
const int smallStrokeDim = nonSimpleLoopsMaxSize * 5;
|
|
Shinya Kitaoka |
120a6e |
bool isSmallStroke = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
set<tpointd> simpleCrossing;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
set<tpointd> nonSimpleCrossing;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class LinkedQuadratic final : public TQuadratic {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *prev, *next;
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic() : TQuadratic(), prev(0), next(0){};
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic(const TPointD &p0, const TPointD &p1, const TPointD &p2)
|
|
Shinya Kitaoka |
120a6e |
: TQuadratic(p0, p1, p2), prev(0), next(0) {}
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic(TQuadratic &Quadratic)
|
|
Shinya Kitaoka |
120a6e |
: TQuadratic(Quadratic), prev(0), next(0) {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef enum Direction {
|
|
Shinya Kitaoka |
120a6e |
inward = 0,
|
|
Shinya Kitaoka |
120a6e |
outward = 1,
|
|
Shinya Kitaoka |
120a6e |
deletedInward = 2,
|
|
Shinya Kitaoka |
120a6e |
deletedOutward = 3
|
|
Campbell Barton |
5cfa87 |
} Direction;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
class CompareOutlines {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
bool operator()(const vector<tquadratic*> &v1,</tquadratic*>
|
|
Shinya Kitaoka |
120a6e |
const vector<tquadratic*> &v2)</tquadratic*>
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if(v1.empty()) return false;
|
|
Shinya Kitaoka |
120a6e |
else if(v2.empty()) return true;
|
|
Shinya Kitaoka |
120a6e |
else return v1[0]->getBBox().y1 > v2[0]->getBBox().y1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
class CompareQuadratics {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
bool operator()(TQuadratic *const q1,
|
|
Shinya Kitaoka |
120a6e |
TQuadratic *const q2)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (q1->getBBox().y1 > q2->getBBox().y1) return true;
|
|
Shinya Kitaoka |
120a6e |
else if (q1->getBBox().y1 < q2->getBBox().y1) return
|
|
Shinya Kitaoka |
120a6e |
false;
|
|
Shinya Kitaoka |
120a6e |
else if (q1->getBBox().x1 > q2->getBBox().x1) return
|
|
Shinya Kitaoka |
120a6e |
true;
|
|
Shinya Kitaoka |
120a6e |
else if (q1->getBBox().x1 < q2->getBBox().x1) return
|
|
Shinya Kitaoka |
120a6e |
false;
|
|
Shinya Kitaoka |
120a6e |
else return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
class CompareLinkedQuadratics {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
bool operator()(const LinkedQuadratic &q1, const LinkedQuadratic &q2) {
|
|
Shinya Kitaoka |
120a6e |
if (q1.getBBox().y1 > q2.getBBox().y1)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
else if (q1.getBBox().y1 < q2.getBBox().y1)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else if (q1.getBBox().x1 > q2.getBBox().x1)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
else if (q1.getBBox().x1 < q2.getBBox().x1)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class CompareBranches {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
bool operator()(const pair<linkedquadratic *,="" direction=""> &b1,</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
const pair<linkedquadratic *,="" direction=""> &b2) {</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
TPointD p1, p2;
|
|
Shinya Kitaoka |
120a6e |
if (b1.second == inward) {
|
|
Shinya Kitaoka |
120a6e |
p1 = b1.first->getP1() - b1.first->getP2();
|
|
Shinya Kitaoka |
120a6e |
} else //(b1.second == outward)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p1 = b1.first->getP1() - b1.first->getP0();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (b2.second == inward) {
|
|
Shinya Kitaoka |
120a6e |
p2 = b2.first->getP1() - b2.first->getP2();
|
|
Shinya Kitaoka |
120a6e |
} else //(b1.second == outward)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p2 = b2.first->getP1() - b2.first->getP0();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double alpha1, alpha2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p1.x > 0)
|
|
Shinya Kitaoka |
120a6e |
alpha1 = -p1.y / sqrt(norm2(p1));
|
|
Shinya Kitaoka |
120a6e |
else if (p1.x < 0)
|
|
Shinya Kitaoka |
120a6e |
alpha1 = 2 + p1.y / sqrt(norm2(p1));
|
|
Shinya Kitaoka |
120a6e |
else //(p1.x = 0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (p1.y > 0)
|
|
Shinya Kitaoka |
120a6e |
alpha1 = -1;
|
|
Shinya Kitaoka |
120a6e |
else if (p1.y < 0)
|
|
Shinya Kitaoka |
120a6e |
alpha1 = 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p2.x > 0)
|
|
Shinya Kitaoka |
120a6e |
alpha2 = -p2.y / sqrt(norm2(p2));
|
|
Shinya Kitaoka |
120a6e |
else if (p2.x < 0)
|
|
Shinya Kitaoka |
120a6e |
alpha2 = 2 + p2.y / sqrt(norm2(p2));
|
|
Shinya Kitaoka |
120a6e |
else //(p2.x = 0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (p2.y > 0)
|
|
Shinya Kitaoka |
120a6e |
alpha2 = -1;
|
|
Shinya Kitaoka |
120a6e |
else if (p2.y < 0)
|
|
Shinya Kitaoka |
120a6e |
alpha2 = 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (alpha2 - alpha1 > 0)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
else if (alpha2 - alpha1 < 0)
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef list<linkedquadratic> LinkedQuadraticList;</linkedquadratic>
|
|
Toshihiro Shimizu |
890ddd |
typedef list<tquadratic> QuadraticList;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
} // namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void splitCircularArcIntoQuadraticCurves(
|
|
shun-iwasawa |
27b0cf |
const TPointD &Center, const TPointD &Pstart, const TPointD &Pend,
|
|
shun-iwasawa |
27b0cf |
vector<tquadratic *=""> &quadArray) {</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
// It splits a circular anticlockwise arc into a sequence of quadratic bezier
|
|
Shinya Kitaoka |
120a6e |
// curves
|
|
Shinya Kitaoka |
120a6e |
// Every quadratic curve can approximate an arc no longer than 45 degrees (or
|
|
Shinya Kitaoka |
120a6e |
// 60).
|
|
Shinya Kitaoka |
120a6e |
// It supposes that Pstart and Pend are onto the circumference (so that their
|
|
Shinya Kitaoka |
120a6e |
// lengths
|
|
Shinya Kitaoka |
120a6e |
// are equal to tha radius of the circumference), otherwise the resulting
|
|
Shinya Kitaoka |
120a6e |
// curves could
|
|
Shinya Kitaoka |
120a6e |
// be unpredictable.
|
|
Shinya Kitaoka |
120a6e |
// The last component in quadCurve[] is an ending void curve
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
// If you want to split the arc into arcs no longer than 45 degrees (so that
|
|
Shinya Kitaoka |
120a6e |
// the whole
|
|
Shinya Kitaoka |
120a6e |
// curve will be splitted into 8 pieces) you have to set these constants as
|
|
Shinya Kitaoka |
120a6e |
// follows:
|
|
Shinya Kitaoka |
120a6e |
// cos_ang ==> cos_45 = 0.5 * sqrt(2);
|
|
Shinya Kitaoka |
120a6e |
// sin_ang ==> sin_45 = 0.5 * sqrt(2);
|
|
Shinya Kitaoka |
120a6e |
// tan_semiang ==> tan_22p5 = 0.4142135623730950488016887242097;
|
|
Shinya Kitaoka |
120a6e |
// N_QUAD = 8;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If you want to split the arc into arcs no longer than 60 degrees (so that
|
|
Shinya Kitaoka |
120a6e |
// the whole
|
|
Shinya Kitaoka |
120a6e |
// curve will be splitted into 6 pieces) you have to set these constants as
|
|
Shinya Kitaoka |
120a6e |
// follows:
|
|
Shinya Kitaoka |
120a6e |
// cos_ang ==> cos_60 = 0.5;
|
|
Shinya Kitaoka |
120a6e |
// sin_ang ==> sin_60 = 0.5 * sqrt(3);
|
|
Shinya Kitaoka |
120a6e |
// tan_semiang ==> tan_30 = 0.57735026918962576450914878050196;
|
|
Shinya Kitaoka |
120a6e |
// N_QUAD = 6;
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Defines some useful constant to split the arc into arcs no longer than
|
|
Shinya Kitaoka |
120a6e |
// 'ang' degrees
|
|
Shinya Kitaoka |
120a6e |
// (the whole circumference will be splitted into 360/ang quadratic curves).
|
|
Shinya Kitaoka |
120a6e |
const double cos_ang = 0.5 * sqrt(2.);
|
|
Shinya Kitaoka |
120a6e |
const double sin_ang = 0.5 * sqrt(2.);
|
|
Shinya Kitaoka |
120a6e |
const double tan_semiang = 0.4142135623730950488016887242097;
|
|
Shinya Kitaoka |
120a6e |
const int N_QUAD = 8; // it's 360/ang
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First of all, it computes the vectors from the center to the circumference,
|
|
Shinya Kitaoka |
120a6e |
// in Pstart and Pend, and their cross and dot products
|
|
Shinya Kitaoka |
120a6e |
TPointD Rstart = Pstart - Center; // its length is R (radius of the circle)
|
|
Shinya Kitaoka |
120a6e |
TPointD Rend = Pend - Center; // its length is R (radius of the circle)
|
|
Shinya Kitaoka |
120a6e |
double cross_prod = cross(Rstart, Rend); // it's Rstart x Rend
|
|
Shinya Kitaoka |
120a6e |
double dot_prod = Rstart * Rend;
|
|
Shinya Kitaoka |
120a6e |
const double sqr_radius = Rstart * Rstart;
|
|
Shinya Kitaoka |
120a6e |
TPointD aliasPstart = Pstart;
|
|
Shinya Kitaoka |
120a6e |
TQuadratic *quad;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while ((cross_prod <= 0) ||
|
|
Shinya Kitaoka |
120a6e |
(dot_prod <= cos_ang * sqr_radius)) // the circular arc is longer
|
|
Shinya Kitaoka |
120a6e |
// than a 'ang' degrees arc
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (quadArray.size() == (UINT)N_QUAD) // this is possible if Pstart or Pend
|
|
Shinya Kitaoka |
120a6e |
// is not onto the circumference
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
TPointD Rstart_rot_ang(cos_ang * Rstart.x - sin_ang * Rstart.y,
|
|
Shinya Kitaoka |
120a6e |
sin_ang * Rstart.x + cos_ang * Rstart.y);
|
|
Shinya Kitaoka |
120a6e |
TPointD Rstart_rot_90(-Rstart.y, Rstart.x);
|
|
Shinya Kitaoka |
120a6e |
quad =
|
|
Shinya Kitaoka |
120a6e |
new TQuadratic(aliasPstart, aliasPstart + tan_semiang * Rstart_rot_90,
|
|
Shinya Kitaoka |
120a6e |
Center + Rstart_rot_ang);
|
|
Shinya Kitaoka |
120a6e |
quadArray.push_back(quad);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// quad->computeMinStepAtNormalSize ();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// And moves anticlockwise the starting point on the circumference by 'ang'
|
|
Shinya Kitaoka |
120a6e |
// degrees
|
|
Shinya Kitaoka |
120a6e |
Rstart = Rstart_rot_ang;
|
|
Shinya Kitaoka |
120a6e |
aliasPstart = quad->getP2();
|
|
Shinya Kitaoka |
120a6e |
cross_prod = cross(Rstart, Rend); // it's Rstart x Rend
|
|
Shinya Kitaoka |
120a6e |
dot_prod = Rstart * Rend;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// after the rotation of 'ang' degrees, the remaining part of the arc could
|
|
Shinya Kitaoka |
120a6e |
// be a 0 degree
|
|
Shinya Kitaoka |
120a6e |
// arc, so it must stop and exit from the function
|
|
Shinya Kitaoka |
120a6e |
if ((cross_prod <= 0) && (dot_prod > 0.95 * sqr_radius)) return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((cross_prod > 0) && (dot_prod > 0)) // the last quadratic curve
|
|
Shinya Kitaoka |
120a6e |
// approximates an arc shorter than a
|
|
Shinya Kitaoka |
120a6e |
// 'ang' degrees arc
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TPointD Rstart_rot_90(-Rstart.y, Rstart.x);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double deg_index = (sqr_radius - dot_prod) / (sqr_radius + dot_prod);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
quad = new TQuadratic(aliasPstart,
|
|
Shinya Kitaoka |
120a6e |
(deg_index < 0)
|
|
Shinya Kitaoka |
120a6e |
? 0.5 * (aliasPstart + Pend)
|
|
Shinya Kitaoka |
120a6e |
: aliasPstart + sqrt(deg_index) * Rstart_rot_90,
|
|
Shinya Kitaoka |
120a6e |
Pend);
|
|
Shinya Kitaoka |
120a6e |
quadArray.push_back(quad);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} else // the last curve, already computed, is as long as a 'ang' degrees arc
|
|
Shinya Kitaoka |
120a6e |
quadArray.back()->setP2(Pend);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool left(const TPointD &a, const TPointD &b, const TPointD &c) {
|
|
Shinya Kitaoka |
120a6e |
double area = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
|
|
Shinya Kitaoka |
120a6e |
return area > 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool right(const TPointD &a, const TPointD &b, const TPointD &c) {
|
|
Shinya Kitaoka |
120a6e |
double area = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
|
|
Shinya Kitaoka |
120a6e |
return area < 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool collinear(const TPointD &a, const TPointD &b, const TPointD &c) {
|
|
Shinya Kitaoka |
120a6e |
double area = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
|
|
Shinya Kitaoka |
120a6e |
return area == 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void computeStrokeBoundary(const TStroke &stroke,
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList &inputBoundaries,
|
|
Shinya Kitaoka |
120a6e |
unsigned int &chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
void normalizeTThickQuadratic(const TThickQuadratic *&sourceThickQuadratic,
|
|
Shinya Kitaoka |
120a6e |
TThickQuadratic &tempThickQuadratic);
|
|
Toshihiro Shimizu |
890ddd |
inline void normalizeTQuadratic(TQuadratic *&sourceQuadratic);
|
|
Shinya Kitaoka |
120a6e |
void getBoundaryPoints(const TPointD &P0, const TPointD &P1,
|
|
Shinya Kitaoka |
120a6e |
const TThickPoint ¢er, TPointD &fwdPoint,
|
|
Shinya Kitaoka |
120a6e |
TPointD &rwdPoint);
|
|
Shinya Kitaoka |
120a6e |
void getAverageBoundaryPoints(const TPointD &P0, const TThickPoint ¢er,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &P2, TPointD &fwdPoint,
|
|
Shinya Kitaoka |
120a6e |
TPointD &rwdPoint);
|
|
Toshihiro Shimizu |
890ddd |
void linkQuadraticList(LinkedQuadraticList &inputBoundaries);
|
|
Toshihiro Shimizu |
890ddd |
void computeInputBoundaries(LinkedQuadraticList &inputBoundaries);
|
|
Toshihiro Shimizu |
890ddd |
void processAdjacentQuadratics(LinkedQuadraticList &inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
void findIntersections(
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *quadratic, set<linkedquadratic *=""> &intersectionWindow,</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
map<linkedquadratic *,="" vector<double="">> &intersectedQuadratics);</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
void refreshIntersectionWindow(LinkedQuadratic *quadratic,
|
|
Shinya Kitaoka |
120a6e |
set<linkedquadratic *=""> &intersectionWindow);</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
void segmentate(LinkedQuadraticList &inputBoundaries,
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *thickQuadratic, vector<double> &splitPoints);</double>
|
|
Toshihiro Shimizu |
890ddd |
void processIntersections(LinkedQuadraticList &intersectionBoundary);
|
|
Shinya Kitaoka |
120a6e |
bool processNonSimpleLoops(
|
|
Shinya Kitaoka |
120a6e |
TPointD &intersectionPoint,
|
|
Shinya Kitaoka |
120a6e |
vector<pair<linkedquadratic *,="" direction="">> &crossing);</pair<linkedquadratic>
|
|
Toshihiro Shimizu |
890ddd |
bool deleteUnlinkedLoops(LinkedQuadraticList &inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
bool getOutputOutlines(LinkedQuadraticList &inputBoundaries,
|
|
Shinya Kitaoka |
120a6e |
vector<tstroke *=""> &sweepStrokes);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
void removeFalseHoles(const vector<tstroke *=""> &strokes);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void TraceLinkedQuadraticList(LinkedQuadraticList &quadraticList) {
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Shinya Kitaoka |
120a6e |
_RPT0(_CRT_WARN, "\n__________________________________________________\n");
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it = quadraticList.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != quadraticList.end()) {
|
|
Shinya Kitaoka |
120a6e |
_RPT4(_CRT_WARN, "\nP0( %f, %f) P2( %f, %f)", it->getP0().x,
|
|
Shinya Kitaoka |
120a6e |
it->getP0().y, it->getP2().x, it->getP2().y);
|
|
Shinya Kitaoka |
120a6e |
_RPT3(_CRT_WARN, " currAddress = %p, nextAddress = %p prevAddress = %p\n",
|
|
Shinya Kitaoka |
120a6e |
&(*it), it->next, it->prev);
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void drawPointSquare(const TPointD &point, double R, double G,
|
|
Shinya Kitaoka |
120a6e |
double B) {
|
|
Toshihiro Shimizu |
890ddd |
#define SQUARE_DIM 0.04
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINE_LOOP);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(R, G, B);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x + SQUARE_DIM, point.y + SQUARE_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x + SQUARE_DIM, point.y - SQUARE_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x - SQUARE_DIM, point.y - SQUARE_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x - SQUARE_DIM, point.y + SQUARE_DIM);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void drawPointCross(const TPointD &point, double R, double G, double B) {
|
|
Toshihiro Shimizu |
890ddd |
#define CROSS_DIM 0.04
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
glColor3d(R, G, B);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x - CROSS_DIM, point.y - CROSS_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x + CROSS_DIM, point.y + CROSS_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x + CROSS_DIM, point.y - CROSS_DIM);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(point.x - CROSS_DIM, point.y + CROSS_DIM);
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static TStroke *getOutStroke(LinkedQuadraticList &inputBoundaries) {
|
|
Shinya Kitaoka |
120a6e |
vector<tpointd> aux;</tpointd>
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
aux.push_back(inputBoundaries.front().getP0());
|
|
Shinya Kitaoka |
120a6e |
for (; it != inputBoundaries.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// if (tdistance2(aux.back(), it->getP2())>0.25)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
aux.push_back(it->getP1());
|
|
Shinya Kitaoka |
120a6e |
aux.push_back(it->getP2());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// inputBoundaries.remove(*it);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return new TStroke(aux);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool getOutputOutlines(LinkedQuadraticList &inputBoundaries,
|
|
Shinya Kitaoka |
120a6e |
vector<tstroke *=""> &sweepStrokes) {</tstroke>
|
|
Shinya Kitaoka |
120a6e |
// int count=0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (!inputBoundaries.empty()) {
|
|
Shinya Kitaoka |
120a6e |
vector<tpointd> v;</tpointd>
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
// std::advance(it, count+1);
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *first = &(*it);
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *toRemove, *current = first;
|
|
Shinya Kitaoka |
120a6e |
v.push_back(current->getP0());
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
// if (tdistance2(v.back(), current->getP2())>0.25)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
v.push_back(current->getP1());
|
|
Shinya Kitaoka |
120a6e |
v.push_back(current->getP2());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// count++;
|
|
Shinya Kitaoka |
120a6e |
// outputOutlines.back().m_quads.push_back(new TQuadratic(*current));
|
|
Shinya Kitaoka |
120a6e |
toRemove = current;
|
|
Shinya Kitaoka |
120a6e |
current = current->next;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*toRemove);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(current);
|
|
Shinya Kitaoka |
120a6e |
if (!current) {
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.clear();
|
|
Shinya Kitaoka |
120a6e |
// outputOutlines.pop_back();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} while (current != first && !inputBoundaries.empty());
|
|
Shinya Kitaoka |
120a6e |
sweepStrokes.push_back(new TStroke(v));
|
|
Shinya Kitaoka |
120a6e |
// sort(outputOutlines[count].begin(), outputOutlines[count].end(),
|
|
Shinya Kitaoka |
38fd86 |
// CompareQuadratics());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.clear();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static bool computeBoundaryStroke(const TStroke &_stroke,
|
|
Campbell Barton |
8c6c57 |
vector<tstroke *=""> &sweepStrokes) {</tstroke>
|
|
Shinya Kitaoka |
120a6e |
// if(!outlines.empty()) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *oriStroke = const_cast<tstroke *="">(&_stroke);</tstroke>
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = oriStroke;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < stroke->getControlPointCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p = stroke->getControlPoint(i);
|
|
Shinya Kitaoka |
120a6e |
// se ci sono punti a spessore nullo, viene male il boundary.
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(p.thick, 0, 1e-8)) {
|
|
Shinya Kitaoka |
120a6e |
if (stroke == oriStroke) stroke = new TStroke(_stroke);
|
|
Shinya Kitaoka |
120a6e |
stroke->setControlPoint(i, TThickPoint(p.x, p.y, 0.0001));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int chunkIndex = 0;
|
|
Shinya Kitaoka |
120a6e |
while (chunkIndex < (UINT)stroke->getChunkCount()) {
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList tempBoundary;
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList inputBoundaries;
|
|
Shinya Kitaoka |
120a6e |
simpleCrossing.clear();
|
|
Shinya Kitaoka |
120a6e |
nonSimpleCrossing.clear();
|
|
Shinya Kitaoka |
120a6e |
isSmallStroke = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
computeStrokeBoundary(*stroke, inputBoundaries, chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.sort(CompareLinkedQuadratics());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
computeInputBoundaries(inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
if (!deleteUnlinkedLoops(inputBoundaries)) return false;
|
|
Shinya Kitaoka |
120a6e |
if (!getOutputOutlines(inputBoundaries, sweepStrokes)) return false;
|
|
Shinya Kitaoka |
120a6e |
// TStroke *sout = getOutStroke(inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
// sweepStrokes.push_back(sout);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if(!getOutputOutlines(inputBoundaries, outlines)) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (stroke != &_stroke) delete stroke;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void computeStrokeBoundary(const TStroke &stroke,
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList &inputBoundaries,
|
|
Shinya Kitaoka |
120a6e |
unsigned int &chunkIndex) {
|
|
Shinya Kitaoka |
120a6e |
unsigned int chunkCount = stroke.getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
assert(chunkCount - chunkIndex > 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((int)(chunkCount - chunkIndex) <= smallStrokeDim) isSmallStroke = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int startIndex = chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *thickQuadratic = 0, *nextThickQuadratic = 0;
|
|
Shinya Kitaoka |
120a6e |
TThickQuadratic tempThickQuadratic, tempNextThickQuadratic;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD fwdP0, fwdP1, fwdP2;
|
|
Shinya Kitaoka |
120a6e |
TPointD rwdP0, rwdP1, rwdP2;
|
|
Shinya Kitaoka |
120a6e |
TPointD nextFwdP0, nextRwdP2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic = stroke.getChunk(chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
while (thickQuadratic->getP0() == thickQuadratic->getP2()) {
|
|
Shinya Kitaoka |
120a6e |
double thickness;
|
|
Shinya Kitaoka |
120a6e |
thickness = std::max({thickQuadratic->getThickP0().thick,
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP1().thick,
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP2().thick});
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
if (chunkIndex == chunkCount) {
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
double thickness = std::max({thickQuadratic->getThickP0().thick,
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP1().thick,
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP2().thick});
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (thickness < thicknessLimit) thickness = thicknessLimit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD center = thickQuadratic->getP0();
|
|
Shinya Kitaoka |
120a6e |
TPointD diameterStart = thickQuadratic->getP0();
|
|
Shinya Kitaoka |
120a6e |
diameterStart.y += thickness;
|
|
Shinya Kitaoka |
120a6e |
TPointD diameterEnd = thickQuadratic->getP0();
|
|
Shinya Kitaoka |
120a6e |
diameterEnd.y -= thickness;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(center, diameterStart, diameterEnd,
|
|
Shinya Kitaoka |
120a6e |
quadArray);
|
|
Shinya Kitaoka |
120a6e |
unsigned int i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
assert(!(quadArray[i]->getP0() == quadArray[i]->getP2()));
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(center, diameterEnd, diameterStart,
|
|
Shinya Kitaoka |
120a6e |
quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
assert(!(quadArray[i]->getP0() == quadArray[i]->getP2()));
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
linkQuadraticList(inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic = stroke.getChunk(chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
normalizeTThickQuadratic(thickQuadratic, tempThickQuadratic);
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(thickQuadratic->getP0(), thickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP0(), fwdP0, rwdP2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!(rwdP2 == fwdP0)) {
|
|
Shinya Kitaoka |
120a6e |
// inputBoundaries.push_front(TQuadratic(rwdP2, (rwdP2+fwdP0)*0.5,
|
|
Shinya Kitaoka |
38fd86 |
// fwdP0));
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves((rwdP2 + fwdP0) * 0.5, rwdP2, fwdP0,
|
|
Shinya Kitaoka |
120a6e |
quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (/*chunkIndex*/; chunkIndex < chunkCount; ++chunkIndex) {
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic = stroke.getChunk(chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
while (thickQuadratic->getP0() == thickQuadratic->getP2()) {
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
if (chunkIndex == chunkCount) break;
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic = stroke.getChunk(chunkIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (chunkIndex >= chunkCount - 1) {
|
|
Shinya Kitaoka |
120a6e |
chunkIndex = chunkCount;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int nextChunkIndex = chunkIndex + 1;
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic = stroke.getChunk(nextChunkIndex);
|
|
Shinya Kitaoka |
120a6e |
while (nextThickQuadratic->getP0() == nextThickQuadratic->getP2()) {
|
|
Shinya Kitaoka |
120a6e |
++nextChunkIndex;
|
|
Shinya Kitaoka |
120a6e |
if (nextChunkIndex == chunkCount) {
|
|
Shinya Kitaoka |
120a6e |
chunkIndex = chunkCount;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic = stroke.getChunk(nextChunkIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (nextChunkIndex == chunkCount) {
|
|
Shinya Kitaoka |
120a6e |
chunkIndex = chunkCount;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (thickQuadratic->getP0() == nextThickQuadratic->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2() == nextThickQuadratic->getP0()) {
|
|
Shinya Kitaoka |
120a6e |
chunkIndex = nextChunkIndex;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (chunkIndex == startIndex + 2 &&
|
|
Shinya Kitaoka |
120a6e |
norm(stroke.getChunk(startIndex)->getP0() -
|
|
Shinya Kitaoka |
120a6e |
stroke.getChunk(chunkCount - 1)->getP2()) <
|
|
Shinya Kitaoka |
120a6e |
stroke.getChunk(startIndex)->getThickP0().thick / 2) {
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
normalizeTThickQuadratic(thickQuadratic, tempThickQuadratic);
|
|
Shinya Kitaoka |
120a6e |
normalizeTThickQuadratic(nextThickQuadratic, tempNextThickQuadratic);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> intersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
TQuadratic quadratic(thickQuadratic->getP0(), thickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2());
|
|
Shinya Kitaoka |
120a6e |
TQuadratic nextQuadratic(nextThickQuadratic->getP0(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP2());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (intersect(quadratic, nextQuadratic, intersections) > 1) {
|
|
Shinya Kitaoka |
120a6e |
double currSplit = 1, nextSplit = 0;
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < intersections.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (currSplit > intersections[i].first)
|
|
Shinya Kitaoka |
120a6e |
currSplit = intersections[i].first;
|
|
Shinya Kitaoka |
120a6e |
if (nextSplit < intersections[i].second)
|
|
Shinya Kitaoka |
120a6e |
nextSplit = intersections[i].second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (currSplit < one && nextSplit > zero && currSplit > 0.5 &&
|
|
Shinya Kitaoka |
120a6e |
nextSplit < 0.5) {
|
|
Shinya Kitaoka |
120a6e |
TQuadratic firstSplit, secondSplit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
quadratic.split(currSplit, firstSplit, secondSplit);
|
|
Shinya Kitaoka |
120a6e |
const_cast<tthickquadratic *="">(thickQuadratic)</tthickquadratic>
|
|
Shinya Kitaoka |
120a6e |
->setP1(firstSplit.getP1());
|
|
Shinya Kitaoka |
120a6e |
const_cast<tthickquadratic *="">(thickQuadratic)</tthickquadratic>
|
|
Shinya Kitaoka |
120a6e |
->setP2(firstSplit.getP2());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
nextQuadratic.split(nextSplit, firstSplit, secondSplit);
|
|
Shinya Kitaoka |
120a6e |
const_cast<tthickquadratic *="">(nextThickQuadratic)</tthickquadratic>
|
|
Shinya Kitaoka |
120a6e |
->setP0(secondSplit.getP0());
|
|
Shinya Kitaoka |
120a6e |
const_cast<tthickquadratic *="">(nextThickQuadratic)</tthickquadratic>
|
|
Shinya Kitaoka |
120a6e |
->setP1(secondSplit.getP1());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getAverageBoundaryPoints(thickQuadratic->getP0(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP1(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2(), fwdP1, rwdP1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(thickQuadratic->getP1(), thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP2(), fwdP2, rwdP0);
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(thickQuadratic->getP2(), nextThickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP2(), nextFwdP0, nextRwdP2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD v1 = thickQuadratic->getP2() - thickQuadratic->getP1();
|
|
Shinya Kitaoka |
120a6e |
TPointD v2 = nextThickQuadratic->getP1() - nextThickQuadratic->getP0();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((v1 * v2) / (norm(v1) * norm(v2)) < -0.95) {
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (nextFwdP0 == fwdP2 && nextRwdP2 == rwdP0) {
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(LinkedQuadratic(rwdP0, rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = fwdP2;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = rwdP0;
|
|
Shinya Kitaoka |
120a6e |
} else if (!(nextFwdP0 == fwdP2) && !(nextRwdP2 == rwdP0)) {
|
|
Shinya Kitaoka |
120a6e |
bool turnLeft, turnRight;
|
|
Shinya Kitaoka |
120a6e |
turnLeft = left(thickQuadratic->getP1(), thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP1());
|
|
Shinya Kitaoka |
120a6e |
turnRight = right(thickQuadratic->getP1(), thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP1());
|
|
Shinya Kitaoka |
120a6e |
if (turnLeft) {
|
|
Shinya Kitaoka |
120a6e |
double thickness = thickQuadratic->getThickP2().thick;
|
|
Shinya Kitaoka |
120a6e |
if (thickness < thicknessLimit) thickness = thicknessLimit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD temp;
|
|
Shinya Kitaoka |
120a6e |
if (rwdP0 + nextRwdP2 - 2 * thickQuadratic->getP2() != TPointD(0, 0)) {
|
|
Shinya Kitaoka |
120a6e |
temp = (normalize(rwdP0 + nextRwdP2 - 2 * thickQuadratic->getP2()) *
|
|
Shinya Kitaoka |
120a6e |
thickness) +
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2();
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
temp = TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(LinkedQuadratic(temp, rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(thickQuadratic->getP2(), fwdP2,
|
|
Shinya Kitaoka |
120a6e |
nextFwdP0, quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = nextFwdP0;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = temp;
|
|
Shinya Kitaoka |
120a6e |
} else if (turnRight) {
|
|
Shinya Kitaoka |
120a6e |
double thickness = thickQuadratic->getThickP2().thick;
|
|
Shinya Kitaoka |
120a6e |
if (thickness < thicknessLimit) thickness = thicknessLimit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD temp;
|
|
Shinya Kitaoka |
120a6e |
if (fwdP2 + nextFwdP0 - 2 * thickQuadratic->getP2() != TPointD(0, 0)) {
|
|
Shinya Kitaoka |
120a6e |
temp = (normalize(fwdP2 + nextFwdP0 - 2 * thickQuadratic->getP2()) *
|
|
Shinya Kitaoka |
120a6e |
thickness) +
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2();
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
temp = TPointD(0, 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(LinkedQuadratic(rwdP0, rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, temp));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(thickQuadratic->getP2(), nextRwdP2,
|
|
Shinya Kitaoka |
120a6e |
rwdP0, quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (int i = quadArray.size() - 1; i >= 0; --i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = temp;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = nextRwdP2;
|
|
Shinya Kitaoka |
120a6e |
} else if (nextFwdP0 == rwdP0 && nextRwdP2 == fwdP2) {
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(collinear(thickQuadratic->getP0(),
|
|
Shinya Kitaoka |
120a6e |
// thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
// nextThickQuadratic->getP2()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!collinear(thickQuadratic->getP0(), thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic(thickQuadratic->getP2(), rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(thickQuadratic->getP2(), fwdP2,
|
|
Shinya Kitaoka |
120a6e |
nextFwdP0, quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = nextFwdP0;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = thickQuadratic->getP2();
|
|
Shinya Kitaoka |
120a6e |
} else if (left(thickQuadratic->getP0(), thickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(thickQuadratic->getP2(), fwdP2,
|
|
Shinya Kitaoka |
120a6e |
nextFwdP0, quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = nextFwdP0;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = rwdP0;
|
|
Shinya Kitaoka |
120a6e |
} else if (right(thickQuadratic->getP0(), thickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
nextThickQuadratic->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(LinkedQuadratic(rwdP0, rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves(thickQuadratic->getP2(), fwdP2,
|
|
Shinya Kitaoka |
120a6e |
nextFwdP0, quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (int i = quadArray.size() - 1; i >= 0; --i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
fwdP0 = fwdP2;
|
|
Shinya Kitaoka |
120a6e |
rwdP2 = nextRwdP2;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// inputBoundaries.push_back(TQuadratic(fwdP0,
|
|
Shinya Kitaoka |
38fd86 |
// fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
// inputBoundaries.push_front(TQuadratic(rwdP0,
|
|
Shinya Kitaoka |
38fd86 |
// rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
// fwdP0 = nextFwdP0;
|
|
Shinya Kitaoka |
120a6e |
// rwdP2 = nextRwdP2;
|
|
Shinya Kitaoka |
120a6e |
++chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
normalizeTThickQuadratic(thickQuadratic, tempThickQuadratic);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if( stroke->getChunk(0)->getP0() ==
|
|
Shinya Kitaoka |
38fd86 |
// stroke->getChunk(chunkCount-1)->getP2() )
|
|
Shinya Kitaoka |
120a6e |
/* if( norm(stroke->getChunk(0)->getP0() - stroke->getChunk(chunkCount-1)->getP2()) <
|
|
Toshihiro Shimizu |
890ddd |
stroke->getChunk(0)->getThickP0().thick/2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
getAverageBoundaryPoints(thickQuadratic->getP0(),
|
|
Toshihiro Shimizu |
890ddd |
thickQuadratic->getThickP1(),
|
|
Toshihiro Shimizu |
890ddd |
thickQuadratic->getP2(),
|
|
Toshihiro Shimizu |
890ddd |
fwdP1,
|
|
Toshihiro Shimizu |
890ddd |
rwdP1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getBoundaryPoints(thickQuadratic->getP1(),
|
|
Toshihiro Shimizu |
890ddd |
thickQuadratic->getP2(),
|
|
Toshihiro Shimizu |
890ddd |
thickQuadratic->getThickPoint(one),
|
|
Toshihiro Shimizu |
890ddd |
fwdP2,
|
|
Toshihiro Shimizu |
890ddd |
rwdP0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inputBoundaries.push_front(TQuadratic(rwdP0, rwdP1, rwdP2));
|
|
Toshihiro Shimizu |
890ddd |
inputBoundaries.push_back(TQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Toshihiro Shimizu |
890ddd |
inputBoundaries.push_back(TQuadratic(fwdP2, (fwdP2+rwdP0)*0.5, rwdP0));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
*/ {
|
|
Shinya Kitaoka |
120a6e |
getAverageBoundaryPoints(thickQuadratic->getP0(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP1(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getP2(), fwdP1, rwdP1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(thickQuadratic->getP1(), thickQuadratic->getP2(),
|
|
Shinya Kitaoka |
120a6e |
thickQuadratic->getThickP2(), fwdP2, rwdP0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_front(LinkedQuadratic(rwdP0, rwdP1, rwdP2));
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(LinkedQuadratic(fwdP0, fwdP1, fwdP2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!(fwdP2 == rwdP0)) {
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> quadArray;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
splitCircularArcIntoQuadraticCurves((fwdP2 + rwdP0) * 0.5, fwdP2, rwdP0,
|
|
Shinya Kitaoka |
120a6e |
quadArray);
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < quadArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (!(quadArray[i]->getP0() == quadArray[i]->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.push_back(*quadArray[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete quadArray[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
quadArray.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
linkQuadraticList(inputBoundaries);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void normalizeTThickQuadratic(
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *&sourceThickQuadratic,
|
|
Shinya Kitaoka |
120a6e |
TThickQuadratic &tempThickQuadratic) {
|
|
Shinya Kitaoka |
120a6e |
assert(!(sourceThickQuadratic->getP0() == sourceThickQuadratic->getP2()));
|
|
Shinya Kitaoka |
120a6e |
if (sourceThickQuadratic->getP0() == sourceThickQuadratic->getP1() ||
|
|
Shinya Kitaoka |
120a6e |
sourceThickQuadratic->getP1() == sourceThickQuadratic->getP2() ||
|
|
Shinya Kitaoka |
120a6e |
collinear(sourceThickQuadratic->getP0(), sourceThickQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
sourceThickQuadratic->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
tempThickQuadratic = *sourceThickQuadratic;
|
|
Shinya Kitaoka |
120a6e |
TThickPoint middleThickPoint(
|
|
Shinya Kitaoka |
120a6e |
(sourceThickQuadratic->getP0() + sourceThickQuadratic->getP2()) * 0.5);
|
|
Shinya Kitaoka |
120a6e |
middleThickPoint.thick = tempThickQuadratic.getThickP1().thick;
|
|
Shinya Kitaoka |
120a6e |
tempThickQuadratic.setThickP1(middleThickPoint);
|
|
Shinya Kitaoka |
120a6e |
sourceThickQuadratic = &tempThickQuadratic;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void normalizeTQuadratic(TQuadratic *&sourceQuadratic) {
|
|
Shinya Kitaoka |
120a6e |
assert(!(sourceQuadratic->getP0() == sourceQuadratic->getP2()));
|
|
Shinya Kitaoka |
120a6e |
if (sourceQuadratic->getP0() == sourceQuadratic->getP1() ||
|
|
Shinya Kitaoka |
120a6e |
sourceQuadratic->getP1() == sourceQuadratic->getP2() ||
|
|
Shinya Kitaoka |
120a6e |
collinear(sourceQuadratic->getP0(), sourceQuadratic->getP1(),
|
|
Shinya Kitaoka |
120a6e |
sourceQuadratic->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
TPointD middleThickPoint(
|
|
Shinya Kitaoka |
120a6e |
(sourceQuadratic->getP0() + sourceQuadratic->getP2()) * 0.5);
|
|
Shinya Kitaoka |
120a6e |
sourceQuadratic->setP1(middleThickPoint);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void getBoundaryPoints(const TPointD &P0, const TPointD &P1,
|
|
Shinya Kitaoka |
120a6e |
const TThickPoint ¢er, TPointD &fwdPoint,
|
|
Shinya Kitaoka |
120a6e |
TPointD &rwdPoint) {
|
|
Shinya Kitaoka |
120a6e |
double thickness = center.thick;
|
|
Shinya Kitaoka |
120a6e |
if (thickness < thicknessLimit) thickness = thicknessLimit;
|
|
Shinya Kitaoka |
120a6e |
// if(P1.y == P0.y)
|
|
Shinya Kitaoka |
120a6e |
if (fabs(P1.y - P0.y) <= 1e-12) {
|
|
Shinya Kitaoka |
120a6e |
if (P1.x - P0.x > 0) {
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y - thickness;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y + thickness;
|
|
Shinya Kitaoka |
120a6e |
} else if (P1.x - P0.x < 0) {
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y + thickness;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y - thickness;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
double m = -(P1.x - P0.x) / (P1.y - P0.y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x + (thickness) / sqrt(1 + m * m);
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y + m * (fwdPoint.x - center.x);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x - (thickness) / sqrt(1 + m * m);
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y + m * (rwdPoint.x - center.x);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(!collinear(P0, P1, rwdPoint));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (left(P0, P1, rwdPoint))
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TPointD temp = fwdPoint;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint = rwdPoint;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint = temp;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void getAverageBoundaryPoints(const TPointD &P0,
|
|
Shinya Kitaoka |
120a6e |
const TThickPoint ¢er,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &P2, TPointD &fwdPoint,
|
|
Shinya Kitaoka |
120a6e |
TPointD &rwdPoint) {
|
|
Shinya Kitaoka |
120a6e |
TPointD fwdP0, fwdP2;
|
|
Shinya Kitaoka |
120a6e |
TPointD rwdP0, rwdP2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(P0, center, center, fwdP0, rwdP0);
|
|
Shinya Kitaoka |
120a6e |
getBoundaryPoints(center, P2, center, fwdP2, rwdP2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double thickness = center.thick;
|
|
Shinya Kitaoka |
120a6e |
if (thickness < thicknessLimit) thickness = thicknessLimit;
|
|
Shinya Kitaoka |
120a6e |
if (fwdP0.x + fwdP2.x == rwdP0.x + rwdP2.x) {
|
|
Shinya Kitaoka |
120a6e |
if ((fwdP0.y + fwdP2.y) - (rwdP0.y + rwdP2.y) > 0) {
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y + thickness;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y - thickness;
|
|
Shinya Kitaoka |
120a6e |
} else if ((fwdP0.y + fwdP2.y) - (rwdP0.y + rwdP2.y) < 0) {
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y - thickness;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y + thickness;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
double m = ((fwdP0.y + fwdP2.y) - (rwdP0.y + rwdP2.y)) /
|
|
Shinya Kitaoka |
120a6e |
((fwdP0.x + fwdP2.x) - (rwdP0.x + rwdP2.x));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.x = center.x + (thickness) / sqrt(1 + m * m);
|
|
Shinya Kitaoka |
120a6e |
fwdPoint.y = center.y + m * (fwdPoint.x - center.x);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.x = center.x - (thickness) / sqrt(1 + m * m);
|
|
Shinya Kitaoka |
120a6e |
rwdPoint.y = center.y + m * (rwdPoint.x - center.x);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (right(P0, center, rwdPoint)) {
|
|
Shinya Kitaoka |
120a6e |
TPointD temp = fwdPoint;
|
|
Shinya Kitaoka |
120a6e |
fwdPoint = rwdPoint;
|
|
Shinya Kitaoka |
120a6e |
rwdPoint = temp;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void linkQuadraticList(LinkedQuadraticList &inputBoundaries) {
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it_curr, it_prev, it_next, it_last;
|
|
Shinya Kitaoka |
120a6e |
it_last = inputBoundaries.end();
|
|
Shinya Kitaoka |
120a6e |
it_last--;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it_curr = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
it_next = it_curr;
|
|
Shinya Kitaoka |
120a6e |
it_next++;
|
|
Shinya Kitaoka |
120a6e |
it_curr->prev = &(*it_last);
|
|
Shinya Kitaoka |
120a6e |
it_curr->next = &(*it_next);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it_curr++;
|
|
Shinya Kitaoka |
120a6e |
it_prev = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
it_next++;
|
|
Shinya Kitaoka |
120a6e |
while (it_curr != it_last) {
|
|
Shinya Kitaoka |
120a6e |
it_curr->prev = &(*it_prev);
|
|
Shinya Kitaoka |
120a6e |
it_curr->next = &(*it_next);
|
|
Shinya Kitaoka |
120a6e |
it_curr++;
|
|
Shinya Kitaoka |
120a6e |
it_prev++;
|
|
Shinya Kitaoka |
120a6e |
it_next++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
it_curr->prev = &(*it_prev);
|
|
Shinya Kitaoka |
120a6e |
it_curr->next = &(*inputBoundaries.begin());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void computeInputBoundaries(LinkedQuadraticList &inputBoundaries) {
|
|
Shinya Kitaoka |
120a6e |
set<linkedquadratic *=""> intersectionWindow;</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
map<linkedquadratic *,="" vector<double="">> intersectedQuadratics;</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList intersectionBoundary;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// detect adjacent quadratics intersections
|
|
Shinya Kitaoka |
120a6e |
processAdjacentQuadratics(inputBoundaries);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// detect Intersections
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it;
|
|
Shinya Kitaoka |
120a6e |
it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != inputBoundaries.end()) {
|
|
Shinya Kitaoka |
120a6e |
assert(!(it->getP0() == it->getP2()));
|
|
Shinya Kitaoka |
120a6e |
refreshIntersectionWindow(&*it, intersectionWindow);
|
|
Shinya Kitaoka |
120a6e |
findIntersections(&*it, intersectionWindow, intersectedQuadratics);
|
|
Shinya Kitaoka |
120a6e |
intersectionWindow.insert(&*it);
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* map<linkedquadratic*, vector<double=""> >::iterator it1 =</linkedquadratic*,>
|
|
Shinya Kitaoka |
120a6e |
intersectedQuadratics.begin();
|
|
Shinya Kitaoka |
120a6e |
while(it1 != intersectedQuadratics.end())
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
_RPT2( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\nP0( %f, %f )\n",
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP0().x,
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP0().y);
|
|
Shinya Kitaoka |
120a6e |
_RPT2( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\nP1( %f, %f )\n",
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP1().x,
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP1().y);
|
|
Shinya Kitaoka |
120a6e |
_RPT2( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\nP2( %f, %f )\n",
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP2().x,
|
|
Shinya Kitaoka |
120a6e |
it1->first->getP2().y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
++it1;
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// segmentate curves
|
|
Shinya Kitaoka |
120a6e |
map<linkedquadratic *,="" vector<double="">>::iterator it_intersectedQuadratics =</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
intersectedQuadratics.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it_intersectedQuadratics != intersectedQuadratics.end()) {
|
|
Shinya Kitaoka |
120a6e |
segmentate(intersectionBoundary, it_intersectedQuadratics->first,
|
|
Shinya Kitaoka |
120a6e |
it_intersectedQuadratics->second);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*it_intersectedQuadratics->first);
|
|
Shinya Kitaoka |
120a6e |
++it_intersectedQuadratics;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// process intersections
|
|
Shinya Kitaoka |
120a6e |
processIntersections(intersectionBoundary);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.sort(CompareLinkedQuadratics());
|
|
Shinya Kitaoka |
120a6e |
intersectionBoundary.sort(CompareLinkedQuadratics());
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.merge(intersectionBoundary, CompareLinkedQuadratics());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void processAdjacentQuadratics(LinkedQuadraticList &inputBoundaries) {
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *start = &inputBoundaries.front();
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *curr = start;
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> intersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *next, *temp;
|
|
Shinya Kitaoka |
120a6e |
next = curr->next;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(curr->getP2() == next->getP0());
|
|
Shinya Kitaoka |
120a6e |
if (curr->getP0() == curr->getP2()) {
|
|
Shinya Kitaoka |
120a6e |
(curr->prev)->next = curr->next;
|
|
Shinya Kitaoka |
120a6e |
(curr->next)->prev = curr->prev;
|
|
Shinya Kitaoka |
120a6e |
temp = curr->prev;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*curr);
|
|
Shinya Kitaoka |
120a6e |
curr = temp;
|
|
Shinya Kitaoka |
120a6e |
} else if (curr->getP0() == next->getP2()) {
|
|
Shinya Kitaoka |
120a6e |
(curr->prev)->next = next->next;
|
|
Shinya Kitaoka |
120a6e |
(next->next)->prev = curr->prev;
|
|
Shinya Kitaoka |
120a6e |
temp = curr->prev;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*curr);
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*next);
|
|
Shinya Kitaoka |
120a6e |
curr = temp;
|
|
Shinya Kitaoka |
120a6e |
} else if ((curr->getP0() == next->getP0()) &&
|
|
Shinya Kitaoka |
120a6e |
(curr->getP1() == next->getP1()) &&
|
|
Shinya Kitaoka |
120a6e |
(curr->getP2() == next->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
(curr)->next = next->next;
|
|
Shinya Kitaoka |
120a6e |
(next->next)->prev = curr;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*next);
|
|
Shinya Kitaoka |
120a6e |
} else if (intersect(*curr, *next, intersections) > 1) {
|
|
Shinya Kitaoka |
120a6e |
double currSplit = 1, nextSplit = 0;
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < intersections.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (currSplit > intersections[i].first)
|
|
Shinya Kitaoka |
120a6e |
currSplit = intersections[i].first;
|
|
Shinya Kitaoka |
120a6e |
if (nextSplit < intersections[i].second)
|
|
Shinya Kitaoka |
120a6e |
nextSplit = intersections[i].second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (currSplit < one && nextSplit > zero) {
|
|
Shinya Kitaoka |
120a6e |
TQuadratic firstSplit, secondSplit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
curr->split(currSplit, firstSplit, secondSplit);
|
|
Shinya Kitaoka |
120a6e |
curr->setP1(firstSplit.getP1());
|
|
Shinya Kitaoka |
120a6e |
curr->setP2(firstSplit.getP2());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
next->split(nextSplit, firstSplit, secondSplit);
|
|
Shinya Kitaoka |
120a6e |
next->setP0(secondSplit.getP0());
|
|
Shinya Kitaoka |
120a6e |
next->setP1(secondSplit.getP1());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
intersections.clear();
|
|
Shinya Kitaoka |
120a6e |
curr = curr->next;
|
|
Shinya Kitaoka |
120a6e |
} while (curr != start);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void findIntersections(
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *quadratic, set<linkedquadratic *=""> &intersectionWindow,</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
map<linkedquadratic *,="" vector<double="">> &intersectedQuadratics) {</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
set<linkedquadratic *="">::iterator it = intersectionWindow.begin();</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
while (it != intersectionWindow.end()) {
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> intersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((quadratic->getP0() == (*it)->getP2()) &&
|
|
Shinya Kitaoka |
120a6e |
(quadratic->getP1() == (*it)->getP1()) &&
|
|
Shinya Kitaoka |
120a6e |
(quadratic->getP2() == (*it)->getP0()))
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
else if ((quadratic->getP0() == (*it)->getP0()) &&
|
|
Shinya Kitaoka |
120a6e |
(quadratic->getP1() == (*it)->getP1()) &&
|
|
Shinya Kitaoka |
120a6e |
(quadratic->getP2() == (*it)->getP2()))
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
else if (quadratic->prev == *it) {
|
|
Shinya Kitaoka |
120a6e |
} else if (quadratic->next == *it) {
|
|
Shinya Kitaoka |
120a6e |
} else if (intersect(*quadratic, *(*it), intersections)) {
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < intersections.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
intersectedQuadratics[quadratic].push_back(intersections[i].first);
|
|
Shinya Kitaoka |
120a6e |
intersectedQuadratics[*it].push_back(intersections[i].second);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
intersections.clear();
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void refreshIntersectionWindow(
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *quadratic, set<linkedquadratic *=""> &intersectionWindow) {</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
set<linkedquadratic *="">::iterator it = intersectionWindow.begin();</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
while (it != intersectionWindow.end()) {
|
|
Shinya Kitaoka |
120a6e |
if ((*it)->getBBox().y0 > quadratic->getBBox().y1) {
|
|
Shinya Kitaoka |
120a6e |
set<linkedquadratic *="">::iterator erase_it;</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
erase_it = it;
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
intersectionWindow.erase(erase_it);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline void segmentate(LinkedQuadraticList &intersectionBoundary,
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *quadratic,
|
|
Shinya Kitaoka |
120a6e |
vector<double> &splitPoints) {</double>
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int k = 0; k < splitPoints.size(); k++) {
|
|
Shinya Kitaoka |
120a6e |
/* _RPT1( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\n%f\n",
|
|
Shinya Kitaoka |
120a6e |
splitPoints[k]);*/
|
|
Shinya Kitaoka |
120a6e |
if (splitPoints[k] > 1) {
|
|
Shinya Kitaoka |
120a6e |
splitPoints[k] = 1;
|
|
Shinya Kitaoka |
120a6e |
} else if (splitPoints[k] < 0) {
|
|
Shinya Kitaoka |
120a6e |
splitPoints[k] = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sort(splitPoints.begin(), splitPoints.end());
|
|
Shinya Kitaoka |
120a6e |
vector<double>::iterator it_duplicates =</double>
|
|
Shinya Kitaoka |
120a6e |
unique(splitPoints.begin(), splitPoints.end());
|
|
Shinya Kitaoka |
120a6e |
splitPoints.erase(it_duplicates, splitPoints.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> segments;</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
split<tquadratic>(*quadratic, splitPoints, segments);</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *prevQuadratic = quadratic->prev;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *="">::iterator it = segments.begin();</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
while (it != segments.end()) {
|
|
Shinya Kitaoka |
120a6e |
if (!((*it)->getP0() == (*it)->getP2())) {
|
|
Shinya Kitaoka |
120a6e |
TQuadratic quad = *(*it);
|
|
Shinya Kitaoka |
120a6e |
normalizeTQuadratic(*it);
|
|
Shinya Kitaoka |
120a6e |
quad = *(*it);
|
|
Shinya Kitaoka |
120a6e |
intersectionBoundary.push_back(*(*it));
|
|
Shinya Kitaoka |
120a6e |
prevQuadratic->next = &intersectionBoundary.back();
|
|
Shinya Kitaoka |
120a6e |
intersectionBoundary.back().prev = prevQuadratic;
|
|
Shinya Kitaoka |
120a6e |
prevQuadratic = &intersectionBoundary.back();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
delete (*it);
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
prevQuadratic->next = quadratic->next;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (quadratic->next) quadratic->next->prev = prevQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void processIntersections(LinkedQuadraticList &intersectionBoundary) {
|
|
Shinya Kitaoka |
120a6e |
vector<pair<linkedquadratic *,="" direction="">> crossing;</pair<linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it1, it2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it1 = intersectionBoundary.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it1 != intersectionBoundary.end()) {
|
|
Shinya Kitaoka |
120a6e |
TPointD intersectionPoint = it1->getP0();
|
|
Shinya Kitaoka |
120a6e |
crossing.push_back(pair<linkedquadratic *,="" direction="">(&(*it1), outward));</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it2 = intersectionBoundary.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it2 != intersectionBoundary.end()) {
|
|
Shinya Kitaoka |
120a6e |
if (it1 != it2) {
|
|
Shinya Kitaoka |
120a6e |
if (it2->getP0() == intersectionPoint) {
|
|
Shinya Kitaoka |
120a6e |
crossing.push_back(
|
|
Shinya Kitaoka |
120a6e |
pair<linkedquadratic *,="" direction="">(&(*it2), outward));</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (it2->getP2() == intersectionPoint) {
|
|
Shinya Kitaoka |
120a6e |
crossing.push_back(
|
|
Shinya Kitaoka |
120a6e |
pair<linkedquadratic *,="" direction="">(&(*it2), inward));</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++it2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int branchNum = crossing.size();
|
|
Shinya Kitaoka |
120a6e |
if (branchNum > 4) {
|
|
Shinya Kitaoka |
120a6e |
if (crossing[0].second == inward)
|
|
Shinya Kitaoka |
120a6e |
nonSimpleCrossing.insert(crossing[0].first->getP2());
|
|
Shinya Kitaoka |
120a6e |
else if (crossing[0].second == outward)
|
|
Shinya Kitaoka |
120a6e |
nonSimpleCrossing.insert(crossing[0].first->getP0());
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
} else if (branchNum > 2 && branchNum <= 4) {
|
|
Shinya Kitaoka |
120a6e |
if (!isSmallStroke) processNonSimpleLoops(intersectionPoint, crossing);
|
|
Shinya Kitaoka |
120a6e |
assert(crossing.size() != 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (crossing[0].second == inward)
|
|
Shinya Kitaoka |
120a6e |
simpleCrossing.insert(crossing[0].first->getP2());
|
|
Shinya Kitaoka |
120a6e |
else if (crossing[0].second == outward)
|
|
Shinya Kitaoka |
120a6e |
simpleCrossing.insert(crossing[0].first->getP0());
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (crossing.size() > 2) {
|
|
Shinya Kitaoka |
120a6e |
sort(crossing.begin(), crossing.end(), CompareBranches());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* _RPT0( _CRT_WARN,
|
|
Toshihiro Shimizu |
890ddd |
"\n__________________________________________________\n");
|
|
Shinya Kitaoka |
120a6e |
for(unsigned int j=0;j
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if(crossing[j].second == inward)
|
|
Shinya Kitaoka |
120a6e |
_RPT2( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\ninward P( %f, %f )\n",
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP1().x -
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP2().x,
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP1().y -
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP2().y);
|
|
Shinya Kitaoka |
120a6e |
else if(crossing[j].second == outward)
|
|
Shinya Kitaoka |
120a6e |
_RPT2( _CRT_WARN,
|
|
Shinya Kitaoka |
120a6e |
"\noutward P( %f, %f )\n",
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP1().x -
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP0().x,
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP1().y -
|
|
Shinya Kitaoka |
120a6e |
crossing[j].first->getP0().y);
|
|
Shinya Kitaoka |
120a6e |
else assert(false);
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<pair<linkedquadratic *,="" direction="">>::iterator it, it_prev,</pair<linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
it_next, it_nextnext, it_prevprev;
|
|
Shinya Kitaoka |
120a6e |
it = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != crossing.end()) {
|
|
Shinya Kitaoka |
120a6e |
if (it->second == outward) {
|
|
Shinya Kitaoka |
120a6e |
it_next = it + 1;
|
|
Shinya Kitaoka |
120a6e |
if (it_next == crossing.end()) it_next = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
while (((it->first)->getP0() == (it_next->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP2() == (it_next->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP1() == (it_next->first)->getP1()) ||
|
|
Shinya Kitaoka |
120a6e |
((it->first)->getP0() == (it_next->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP2() == (it_next->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP1() == (it_next->first)->getP1())) {
|
|
Shinya Kitaoka |
120a6e |
it_next = it_next + 1;
|
|
Shinya Kitaoka |
120a6e |
if (it_next == crossing.end()) it_next = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
it_nextnext = it_next + 1;
|
|
Shinya Kitaoka |
120a6e |
if (it_nextnext == crossing.end()) it_nextnext = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
if (((it_nextnext->first)->getP0() == (it_next->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it_nextnext->first)->getP2() == (it_next->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it_nextnext->first)->getP1() == (it_next->first)->getP1()) ||
|
|
Shinya Kitaoka |
120a6e |
((it_nextnext->first)->getP0() == (it_next->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it_nextnext->first)->getP2() == (it_next->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it_nextnext->first)->getP1() == (it_next->first)->getP1())) {
|
|
Shinya Kitaoka |
120a6e |
if (it_nextnext->second == outward ||
|
|
Shinya Kitaoka |
120a6e |
it_nextnext->second == deletedOutward) {
|
|
Shinya Kitaoka |
120a6e |
it->first->prev = 0;
|
|
Shinya Kitaoka |
120a6e |
it->second = deletedOutward;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (it_next->second == outward ||
|
|
Shinya Kitaoka |
120a6e |
it_next->second == deletedOutward) {
|
|
Shinya Kitaoka |
120a6e |
it->first->prev = 0;
|
|
Shinya Kitaoka |
120a6e |
it->second = deletedOutward;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else //(it->second == inward)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (it == crossing.begin())
|
|
Shinya Kitaoka |
120a6e |
it_prev = crossing.end() - 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
it_prev = it - 1;
|
|
Shinya Kitaoka |
120a6e |
while (((it->first)->getP0() == (it_prev->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP2() == (it_prev->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP1() == (it_prev->first)->getP1()) ||
|
|
Shinya Kitaoka |
120a6e |
((it->first)->getP0() == (it_prev->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP2() == (it_prev->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it->first)->getP1() == (it_prev->first)->getP1())) {
|
|
Shinya Kitaoka |
120a6e |
if (it_prev == crossing.begin())
|
|
Shinya Kitaoka |
120a6e |
it_prev = crossing.end() - 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
it_prev = it_prev - 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (it_prev == crossing.begin())
|
|
Shinya Kitaoka |
120a6e |
it_prevprev = crossing.end() - 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
it_prevprev = it_prev - 1;
|
|
Shinya Kitaoka |
120a6e |
if (((it_prevprev->first)->getP0() == (it_prev->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it_prevprev->first)->getP2() == (it_prev->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it_prevprev->first)->getP1() == (it_prev->first)->getP1()) ||
|
|
Shinya Kitaoka |
120a6e |
((it_prevprev->first)->getP0() == (it_prev->first)->getP0() &&
|
|
Shinya Kitaoka |
120a6e |
(it_prevprev->first)->getP2() == (it_prev->first)->getP2() &&
|
|
Shinya Kitaoka |
120a6e |
(it_prevprev->first)->getP1() == (it_prev->first)->getP1())) {
|
|
Shinya Kitaoka |
120a6e |
if (it_prevprev->second == inward ||
|
|
Shinya Kitaoka |
120a6e |
it_prevprev->second == deletedInward) {
|
|
Shinya Kitaoka |
120a6e |
it->first->next = 0;
|
|
Shinya Kitaoka |
120a6e |
it->second = deletedInward;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (it_prev->second == inward || it_prev->second == deletedInward) {
|
|
Shinya Kitaoka |
120a6e |
it->first->next = 0;
|
|
Shinya Kitaoka |
120a6e |
it->second = deletedInward;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
it = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != crossing.end()) {
|
|
Shinya Kitaoka |
120a6e |
if (it->second == deletedOutward || it->second == deletedInward)
|
|
Shinya Kitaoka |
120a6e |
it = crossing.erase(it);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(crossing.size() > 0 && crossing.size() <= 4);
|
|
Shinya Kitaoka |
120a6e |
if (crossing.size() == 0) {
|
|
Shinya Kitaoka |
120a6e |
} else if (crossing.size() == 2) {
|
|
Shinya Kitaoka |
120a6e |
if (crossing[0].second == inward) {
|
|
Shinya Kitaoka |
120a6e |
assert(crossing[1].second == outward);
|
|
Shinya Kitaoka |
120a6e |
crossing[0].first->next = crossing[1].first;
|
|
Shinya Kitaoka |
120a6e |
crossing[1].first->prev = crossing[0].first;
|
|
Shinya Kitaoka |
120a6e |
} else // if(crossing[0].second == outward)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(crossing[1].second == inward);
|
|
Shinya Kitaoka |
120a6e |
crossing[0].first->prev = crossing[1].first;
|
|
Shinya Kitaoka |
120a6e |
crossing[1].first->next = crossing[0].first;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
crossing.clear();
|
|
Shinya Kitaoka |
120a6e |
++it1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool processNonSimpleLoops(
|
|
Shinya Kitaoka |
120a6e |
TPointD &intersectionPoint,
|
|
Shinya Kitaoka |
120a6e |
vector<pair<linkedquadratic *,="" direction="">> &crossing) {</pair<linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
vector<pair<linkedquadratic *,="" direction="">>::iterator it, last;</pair<linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
it = crossing.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != crossing.end()) {
|
|
Shinya Kitaoka |
120a6e |
if (it->second == outward || it->second == deletedOutward) {
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *loopStart = it->first;
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *loopCurr = loopStart;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < nonSimpleLoopsMaxSize; ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (loopCurr->getP2() == intersectionPoint) {
|
|
Shinya Kitaoka |
120a6e |
loopStart->prev = 0;
|
|
Shinya Kitaoka |
120a6e |
crossing.erase(it);
|
|
Shinya Kitaoka |
120a6e |
loopCurr->next = 0;
|
|
Shinya Kitaoka |
120a6e |
last = remove(crossing.begin(), crossing.end(),
|
|
Shinya Kitaoka |
120a6e |
pair<linkedquadratic *,="" direction="">(loopCurr, inward));</linkedquadratic>
|
|
Shinya Kitaoka |
120a6e |
crossing.erase(last, crossing.end());
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!loopCurr->next) break;
|
|
Shinya Kitaoka |
120a6e |
double distance = norm2(loopCurr->getP0() - loopCurr->next->getP2());
|
|
Shinya Kitaoka |
120a6e |
if (distance > nonSimpleLoopsMaxDistance) break;
|
|
Shinya Kitaoka |
120a6e |
loopCurr = loopCurr->next;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool deleteUnlinkedLoops(LinkedQuadraticList &inputBoundaries) {
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadratic *current, *temp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinkedQuadraticList::iterator it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
while (it != inputBoundaries.end()) {
|
|
Shinya Kitaoka |
120a6e |
// bool isNonSimpleBranch;
|
|
Shinya Kitaoka |
120a6e |
int count;
|
|
Shinya Kitaoka |
120a6e |
if (it->prev == 0) {
|
|
Shinya Kitaoka |
120a6e |
// if( nonSimpleCrossing.find(it->getP0()) !=
|
|
Shinya Kitaoka |
38fd86 |
// nonSimpleCrossing.end() )
|
|
Shinya Kitaoka |
120a6e |
// isNonSimpleBranch = true;
|
|
Shinya Kitaoka |
120a6e |
// else isNonSimpleBranch = false;
|
|
Shinya Kitaoka |
120a6e |
count = inputBoundaries.size();
|
|
Shinya Kitaoka |
120a6e |
current = &(*it);
|
|
Shinya Kitaoka |
120a6e |
while (current != 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(count > 0);
|
|
Shinya Kitaoka |
120a6e |
if (count == 0) return false;
|
|
Shinya Kitaoka |
120a6e |
if (nonSimpleCrossing.find(current->getP2()) != nonSimpleCrossing.end())
|
|
Shinya Kitaoka |
38fd86 |
// ||
|
|
Shinya Kitaoka |
d1f6c4 |
// simpleCrossing.find(current->getP2())
|
|
Shinya Kitaoka |
120a6e |
//!= simpleCrossing.end() )
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (current->next) current->next->prev = 0;
|
|
Shinya Kitaoka |
120a6e |
it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (&(*it) == current) ++it;
|
|
Shinya Kitaoka |
120a6e |
temp = current->next;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*current);
|
|
Shinya Kitaoka |
120a6e |
if (temp) {
|
|
Shinya Kitaoka |
120a6e |
assert(temp->next != current);
|
|
Shinya Kitaoka |
120a6e |
if (temp->next == current) {
|
|
Shinya Kitaoka |
120a6e |
temp->next = 0;
|
|
Shinya Kitaoka |
120a6e |
it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
current = temp;
|
|
Shinya Kitaoka |
120a6e |
--count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (it->next == 0) {
|
|
Shinya Kitaoka |
120a6e |
// if( nonSimpleCrossing.find(it->getP2()) !=
|
|
Shinya Kitaoka |
38fd86 |
// nonSimpleCrossing.end() )
|
|
Shinya Kitaoka |
120a6e |
// isNonSimpleBranch = true;
|
|
Shinya Kitaoka |
120a6e |
// else isNonSimpleBranch = false;
|
|
Shinya Kitaoka |
120a6e |
count = inputBoundaries.size();
|
|
Shinya Kitaoka |
120a6e |
current = &(*it);
|
|
Shinya Kitaoka |
120a6e |
while (current != 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(count > 0);
|
|
Shinya Kitaoka |
120a6e |
if (count == 0) return false;
|
|
Shinya Kitaoka |
120a6e |
if (nonSimpleCrossing.find(current->getP0()) != nonSimpleCrossing.end())
|
|
Shinya Kitaoka |
38fd86 |
// ||
|
|
Shinya Kitaoka |
d1f6c4 |
// simpleCrossing.find(current->getP0())
|
|
Shinya Kitaoka |
120a6e |
//!= simpleCrossing.end() )
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (current->prev) current->prev->next = 0;
|
|
Shinya Kitaoka |
120a6e |
it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (&(*it) == current) ++it;
|
|
Shinya Kitaoka |
120a6e |
temp = current->prev;
|
|
Shinya Kitaoka |
120a6e |
inputBoundaries.remove(*current);
|
|
Shinya Kitaoka |
120a6e |
if (temp) {
|
|
Shinya Kitaoka |
120a6e |
assert(temp->prev != current);
|
|
Shinya Kitaoka |
120a6e |
if (temp->prev == current) {
|
|
Shinya Kitaoka |
120a6e |
temp->prev = 0;
|
|
Shinya Kitaoka |
120a6e |
it = inputBoundaries.begin();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
current = temp;
|
|
Shinya Kitaoka |
120a6e |
--count;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
++it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LEVO
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void computeIntersections(IntersectionData &intData,
|
|
Shinya Kitaoka |
120a6e |
const vector<tstroke *=""> &strokeArray);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void addBranch(IntersectionData &intData, list<intersectedstroke> &strokeList,</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
const vector<tstroke *=""> &s, int ii, double w) {</tstroke>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
TPointD tan1, tan2;
|
|
Shinya Kitaoka |
120a6e |
double crossVal;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke item(intData.m_intList.end(), strokeList.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item.m_edge.m_s = s[ii];
|
|
Shinya Kitaoka |
120a6e |
item.m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
item.m_edge.m_w0 = w;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tan1 = item.m_edge.m_s->getSpeed(w);
|
|
Shinya Kitaoka |
120a6e |
tan2 = ((strokeList.back().m_gettingOut) ? 1 : -1) *
|
|
Shinya Kitaoka |
120a6e |
strokeList.back().m_edge.m_s->getSpeed(strokeList.back().m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (strokeList.size() == 2) // potrebbero essere orientati male; due branch
|
|
Shinya Kitaoka |
120a6e |
// possono stare come vogliono, ma col terzo no.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TPointD aux = ((strokeList.begin()->m_gettingOut) ? 1 : -1) *
|
|
Shinya Kitaoka |
120a6e |
strokeList.begin()->m_edge.m_s->getSpeed(
|
|
Shinya Kitaoka |
120a6e |
strokeList.begin()->m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
if (cross(aux, tan2) > 0) {
|
|
Shinya Kitaoka |
120a6e |
std::reverse(strokeList.begin(), strokeList.end());
|
|
Shinya Kitaoka |
120a6e |
tan2 =
|
|
Shinya Kitaoka |
120a6e |
((strokeList.back().m_gettingOut) ? 1 : -1) *
|
|
Shinya Kitaoka |
120a6e |
strokeList.back().m_edge.m_s->getSpeed(strokeList.back().m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double lastCross = cross(tan1, tan2);
|
|
Shinya Kitaoka |
120a6e |
// UINT size = strokeList.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UINT added = 0;
|
|
Shinya Kitaoka |
120a6e |
bool endPoint = (w == 0.0 || w == 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it = strokeList.begin(); it != strokeList.end(); it++) {
|
|
Shinya Kitaoka |
120a6e |
tan2 = (((*it).m_gettingOut) ? 1 : -1) *
|
|
Shinya Kitaoka |
120a6e |
(*it).m_edge.m_s->getSpeed((*it).m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
crossVal = cross(tan1, tan2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (lastCross > 0 && crossVal < 0 && w != 1.0) {
|
|
Shinya Kitaoka |
120a6e |
assert(added != 0x1);
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = true;
|
|
Shinya Kitaoka |
120a6e |
strokeList.insert(it, item);
|
|
Shinya Kitaoka |
120a6e |
added |= 0x1;
|
|
Shinya Kitaoka |
120a6e |
if (endPoint || added == 0x3) return;
|
|
Shinya Kitaoka |
120a6e |
} else if (lastCross < 0 && crossVal > 0 && w != 0.0) {
|
|
Shinya Kitaoka |
120a6e |
assert(added != 0x2);
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = false;
|
|
Shinya Kitaoka |
120a6e |
strokeList.insert(it, item);
|
|
Shinya Kitaoka |
120a6e |
added |= 0x2;
|
|
Shinya Kitaoka |
120a6e |
if (endPoint || added == 0x3) return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
lastCross = crossVal;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (endPoint) {
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = (w == 0.0);
|
|
Shinya Kitaoka |
120a6e |
strokeList.push_back(item);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = (crossVal >= 0);
|
|
Shinya Kitaoka |
120a6e |
strokeList.push_back(item);
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = !item.m_gettingOut;
|
|
Shinya Kitaoka |
120a6e |
strokeList.push_back(item);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addBranches(IntersectionData &intData, Intersection &intersection,
|
|
Shinya Kitaoka |
120a6e |
const vector<tstroke *=""> &s, int ii, int jj,</tstroke>
|
|
Shinya Kitaoka |
120a6e |
DoublePair intersectionPair) {
|
|
Shinya Kitaoka |
120a6e |
bool foundS1 = false, foundS2 = false;
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(!intersection.m_strokeList.empty());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it = intersection.m_strokeList.begin();
|
|
Shinya Kitaoka |
120a6e |
it != intersection.m_strokeList.end(); it++) {
|
|
Shinya Kitaoka |
120a6e |
if ((ii >= 0 && (*it).m_edge.m_s == s[ii])) foundS1 = true;
|
|
Shinya Kitaoka |
120a6e |
if ((jj >= 0 && (*it).m_edge.m_s == s[jj])) foundS2 = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (foundS1 && foundS2) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!foundS1) {
|
|
Shinya Kitaoka |
120a6e |
int size = intersection.m_strokeList.size();
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, ii,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.first);
|
|
Shinya Kitaoka |
120a6e |
assert(intersection.m_strokeList.size() - size > 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!foundS2) {
|
|
Shinya Kitaoka |
120a6e |
int size = intersection.m_strokeList.size();
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, jj,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.second);
|
|
Shinya Kitaoka |
120a6e |
// intersection.m_numInter+=intersection.m_strokeList.size()-size;
|
|
Shinya Kitaoka |
120a6e |
assert(intersection.m_strokeList.size() - size > 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef IS_DOTNET
|
|
Toshihiro Shimizu |
890ddd |
#define NULL_ITER list<intersectedstroke>::iterator()</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define NULL_ITER 0
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
Intersection makeIntersection(IntersectionData &intData,
|
|
Shinya Kitaoka |
120a6e |
const vector<tstroke *=""> &s, int ii, int jj,</tstroke>
|
|
Shinya Kitaoka |
120a6e |
DoublePair inter) {
|
|
Shinya Kitaoka |
120a6e |
Intersection interList;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke item1(intData.m_intList.end(), NULL_ITER),
|
|
Shinya Kitaoka |
120a6e |
item2(intData.m_intList.end(), NULL_ITER);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
interList.m_intersection = s[ii]->getPoint(inter.first);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_w0 = inter.first;
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_w0 = inter.second;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_s = s[ii];
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s = s[jj];
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_index = jj;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool reversed = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (cross(item1.m_edge.m_s->getSpeed(inter.first),
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s->getSpeed(inter.second)) > 0)
|
|
Shinya Kitaoka |
120a6e |
reversed = true; // std::reverse(interList.m_strokeList.begin(),
|
|
Shinya Kitaoka |
120a6e |
// interList.m_strokeList.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (item1.m_edge.m_w0 != 1.0) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_gettingOut = true;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.push_back(item1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item2.m_edge.m_w0 != (reversed ? 0.0 : 1.0)) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_gettingOut = !reversed;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.push_back(item2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item1.m_edge.m_w0 != 0.0) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_gettingOut = false;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.push_back(item1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item2.m_edge.m_w0 != (reversed ? 1.0 : 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_gettingOut = reversed;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.push_back(item2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return interList;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addIntersection(IntersectionData &intData, const vector<tstroke *=""> &s,</tstroke>
|
|
Shinya Kitaoka |
120a6e |
int ii, int jj, DoublePair intersection) {
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it;</intersection>
|
|
Shinya Kitaoka |
120a6e |
TPointD p;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(intersection.first, 0.0, 1e-9))
|
|
Shinya Kitaoka |
120a6e |
intersection.first = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(intersection.first, 1.0, 1e-9))
|
|
Shinya Kitaoka |
120a6e |
intersection.first = 1.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(intersection.second, 0.0, 1e-9))
|
|
Shinya Kitaoka |
120a6e |
intersection.second = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(intersection.second, 1.0, 1e-9))
|
|
Shinya Kitaoka |
120a6e |
intersection.second = 1.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p = s[ii]->getPoint(intersection.first);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it = intData.m_intList.begin(); it != intData.m_intList.end(); it++)
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual((*it).m_intersection,
|
|
Shinya Kitaoka |
120a6e |
p)) // devono essere rigorosamente uguali, altrimenti
|
|
Shinya Kitaoka |
120a6e |
// il calcolo dell'ordine dei rami con le tangenti sballa
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if ((*it).m_intersection == p)
|
|
Shinya Kitaoka |
120a6e |
addBranches(intData, *it, s, ii, jj, intersection);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
intData.m_intList.push_back(
|
|
Shinya Kitaoka |
120a6e |
makeIntersection(intData, s, ii, jj, intersection));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void findNearestIntersection(list<intersection> &interList) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator i1;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator i2;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i1 = interList.begin(); i1 != interList.end(); i1++) {
|
|
Shinya Kitaoka |
120a6e |
for (i2 = (*i1).m_strokeList.begin(); i2 != (*i1).m_strokeList.end();
|
|
Shinya Kitaoka |
120a6e |
i2++) {
|
|
Shinya Kitaoka |
120a6e |
if ((*i2).m_nextIntersection != interList.end()) // already set
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int versus = (i2->m_gettingOut) ? 1 : -1;
|
|
Shinya Kitaoka |
120a6e |
double minDelta = (std::numeric_limits<double>::max)();</double>
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it1, it1Res;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it2, it2Res;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it1 = i1; it1 != interList.end(); ++it1) {
|
|
Shinya Kitaoka |
120a6e |
if (it1 == i1)
|
|
Shinya Kitaoka |
120a6e |
it2 = i2, it2++;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
it2 = (*it1).m_strokeList.begin();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (; it2 != (*it1).m_strokeList.end(); ++it2) {
|
|
Shinya Kitaoka |
120a6e |
if ((*it2).m_edge.m_index == i2->m_edge.m_index &&
|
|
Shinya Kitaoka |
120a6e |
(*it2).m_gettingOut == !i2->m_gettingOut) {
|
|
Shinya Kitaoka |
120a6e |
double delta = versus * (it2->m_edge.m_w0 - i2->m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (delta > 0 && delta < minDelta) {
|
|
Shinya Kitaoka |
120a6e |
it1Res = it1;
|
|
Shinya Kitaoka |
120a6e |
it2Res = it2;
|
|
Shinya Kitaoka |
120a6e |
minDelta = delta;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (minDelta != (std::numeric_limits<double>::max)()) {</double>
|
|
Shinya Kitaoka |
120a6e |
(*it2Res).m_nextIntersection = i1;
|
|
Shinya Kitaoka |
120a6e |
(*it2Res).m_nextStroke = i2;
|
|
Shinya Kitaoka |
120a6e |
(*it2Res).m_edge.m_w1 = i2->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
(*i2).m_nextIntersection = it1Res;
|
|
Shinya Kitaoka |
120a6e |
(*i2).m_nextStroke = it2Res;
|
|
Shinya Kitaoka |
120a6e |
(*i2).m_edge.m_w1 = it2Res->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
i1->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
it1Res->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int myIntersect(const TStroke *s1, const TStroke *s2,
|
|
Shinya Kitaoka |
120a6e |
std::vector<doublepair> &intersections) {</doublepair>
|
|
Shinya Kitaoka |
120a6e |
int k = 0;
|
|
Shinya Kitaoka |
120a6e |
assert(s1 != s2);
|
|
Shinya Kitaoka |
120a6e |
intersections.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < s1->getChunkCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < s2->getChunkCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const TQuadratic *q1 = s1->getChunk(i);
|
|
Shinya Kitaoka |
120a6e |
const TQuadratic *q2 = s2->getChunk(j);
|
|
Shinya Kitaoka |
120a6e |
if (!q1->getBBox().overlaps(q2->getBBox())) continue;
|
|
Shinya Kitaoka |
120a6e |
if (intersect(*q1, *q2, intersections) > k)
|
|
Shinya Kitaoka |
120a6e |
while (k < (int)intersections.size()) {
|
|
Shinya Kitaoka |
120a6e |
intersections[k].first =
|
|
Shinya Kitaoka |
120a6e |
getWfromChunkAndT(s1, i, intersections[k].first);
|
|
Shinya Kitaoka |
120a6e |
intersections[k].second =
|
|
Shinya Kitaoka |
120a6e |
getWfromChunkAndT(s2, j, intersections[k].second);
|
|
Shinya Kitaoka |
120a6e |
k++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return k;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void computeIntersections(IntersectionData &intData,
|
|
Shinya Kitaoka |
120a6e |
const vector<tstroke *=""> &strokeArray) {</tstroke>
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(intData.m_intersectedStrokeArray.empty());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it1;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it2;</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)strokeArray.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = strokeArray[i];
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, strokeArray, i, i,
|
|
Shinya Kitaoka |
120a6e |
DoublePair(0, 1)); // le stroke sono sicuramente selfloop!
|
|
Shinya Kitaoka |
120a6e |
for (j = i + 1; j < (int)strokeArray.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = strokeArray[j];
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> intersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
if (s1->getBBox().overlaps(s2->getBBox()) &&
|
|
Shinya Kitaoka |
120a6e |
myIntersect(s1, s2, intersections))
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < (int)intersections.size(); k++)
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, strokeArray, i, j, intersections[k]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// la struttura delle intersezioni viene poi visitata per trovare
|
|
Shinya Kitaoka |
120a6e |
// i link tra un'intersezione e la successiva
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
findNearestIntersection(intData.m_intList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// for (it1=intData.m_intList.begin(); it1!=intData.m_intList.end();) //la
|
|
Shinya Kitaoka |
120a6e |
// faccio qui, e non nella eraseIntersection. vedi commento li'.
|
|
Shinya Kitaoka |
120a6e |
// eraseDeadIntersections(intData.m_intList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// for (it1=intData.m_intList.begin(); it1!=intData.m_intList.end(); it1++)
|
|
Shinya Kitaoka |
120a6e |
// markDeadIntersections(intData.m_intList, it1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// checkInterList(intData.m_intList);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *findRegion(list<intersection> &intList,</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it1,</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it2);</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool isValidArea(const TRegion &r);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool computeSweepBoundary(const vector<tstroke *=""> &strokes,</tstroke>
|
|
Shinya Kitaoka |
120a6e |
vector<vector<tquadratic *="">> &outlines) {</vector<tquadratic>
|
|
Shinya Kitaoka |
120a6e |
if (strokes.empty()) return false;
|
|
Shinya Kitaoka |
120a6e |
// if(!outlines.empty()) return false;
|
|
Shinya Kitaoka |
120a6e |
vector<tstroke *=""> sweepStrokes;</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
computeBoundaryStroke(*strokes[i], sweepStrokes);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*if (Count)
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
Count++;*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ofstream of("c:\\temp\\boh.txt");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < sweepStrokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
// of<<"****sweepstroke #"<
|
|
Shinya Kitaoka |
120a6e |
outlines.push_back(vector<tquadratic *="">());</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
vector<tquadratic *=""> &q = outlines.back();</tquadratic>
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < sweepStrokes[i]->getChunkCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q0 = sweepStrokes[i]->getChunk(j);
|
|
Shinya Kitaoka |
120a6e |
// of<<"q"<<j<<": "<<q0-="">getP0().x<<", "<<q0->getP0().y<</q0-></j<<":>
|
|
Shinya Kitaoka |
120a6e |
// of<<" "<< q0->getP1().x<<", "<<q0->getP1().y<</q0->
|
|
Shinya Kitaoka |
120a6e |
// of<<" "<< q0->getP2().x<<", "<<q0->getP2().y<</q0->
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
q.push_back(new TQuadratic(*q0));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// computeRegions(sweepStrokes, outlines);
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(sweepStrokes);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LEVO
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *findRegion(list<intersection> &intList,</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it1,</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it2) {</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = new TRegion();
|
|
Shinya Kitaoka |
120a6e |
// int currStyle=0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator itStart = it2;</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator nextIt1;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator nextIt2;</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (!(*it2).m_visited) {
|
|
Shinya Kitaoka |
120a6e |
(*it2).m_visited = true;
|
|
Shinya Kitaoka |
120a6e |
if ((*it2).m_edge.m_w0 >= (*it2).m_edge.m_w1) {
|
|
Shinya Kitaoka |
120a6e |
delete r;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
it2++;
|
|
Shinya Kitaoka |
120a6e |
if (it2 == ((*it1).m_strokeList.end())) // la lista e' circolare
|
|
Shinya Kitaoka |
120a6e |
it2 = (*it1).m_strokeList.begin();
|
|
Shinya Kitaoka |
120a6e |
} while (it2->m_nextIntersection == intList.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
nextIt1 = (*it2).m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
nextIt2 = (*it2).m_nextStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
r->addEdge(&(*it2).m_edge);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (nextIt2 == itStart) return r;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
it1 = nextIt1;
|
|
Shinya Kitaoka |
120a6e |
it2 = nextIt2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete r;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
bool isValidArea(const TRegion &r) {
|
|
Shinya Kitaoka |
120a6e |
int size = r.getEdgeCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (size == 0) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < size; i++) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r.getEdge(i);
|
|
Shinya Kitaoka |
120a6e |
if (e->m_w0 < e->m_w1) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|