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