|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tregionprop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurveutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/numeric_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/poly_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// STD includes
|
|
Toshihiro Shimizu |
890ddd |
#include <set></set>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//DEFINE_CLASS_CODE(TEdge, 40)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void foo()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdgeP p1 = new TEdge();
|
|
Toshihiro Shimizu |
890ddd |
TEdgeP p2 = new TEdge(*p1);
|
|
Toshihiro Shimizu |
890ddd |
p1 = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = new TEdge;
|
|
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 |
bool compareEdge(const TEdge &a,
|
|
Toshihiro Shimizu |
890ddd |
const TEdge &b)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return a.m_s == b.m_s;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TRegion::Imp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double m_polyStep;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
TRegionProp *m_prop;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mutable TRectD m_bBox;
|
|
Toshihiro Shimizu |
890ddd |
mutable bool m_isValidBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<tedge *=""> m_edge;</tedge>
|
|
Toshihiro Shimizu |
890ddd |
std::vector<tregion *=""> m_includedRegionArray;</tregion>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Imp()
|
|
Toshihiro Shimizu |
890ddd |
: m_polyStep(-1), m_prop(0), m_bBox(), m_isValidBBox(true), m_edge(), m_includedRegionArray() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~Imp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_prop;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
delete m_includedRegionArray[i];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void printContains(const TPointD &p) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void invalidateBBox() { m_isValidBBox = false; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
void checkRegion()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_edge.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = m_edge[i];
|
|
Toshihiro Shimizu |
890ddd |
assert(e->getStyle() >= 0 && e->getStyle() <= 1000);
|
|
Toshihiro Shimizu |
890ddd |
assert(e->m_w0 >= 0 && e->m_w1 <= 1);
|
|
Toshihiro Shimizu |
890ddd |
assert(e->m_s->getChunkCount() >= 0 && e->m_s->getChunkCount() <= 10000);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD getBBox() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_isValidBBox) {
|
|
Toshihiro Shimizu |
890ddd |
m_bBox = TRectD();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_edge.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
m_bBox += m_edge[i]->m_s->getBBox(tmin(m_edge[i]->m_w0, m_edge[i]->m_w1),
|
|
Toshihiro Shimizu |
890ddd |
tmax(m_edge[i]->m_w0, m_edge[i]->m_w1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_isValidBBox = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return m_bBox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool contains(const TPointD &p) const;
|
|
Toshihiro Shimizu |
890ddd |
bool contains(const TRegion::Imp &p) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//this function returns true only if p is contained in the region, taking into account holes in it.
|
|
Toshihiro Shimizu |
890ddd |
bool noSubregionContains(const TPointD &p) const;
|
|
Toshihiro Shimizu |
890ddd |
void addSubregion(TRegion *region);
|
|
Toshihiro Shimizu |
890ddd |
// bool getPointInside(TPointD &p) const;
|
|
Toshihiro Shimizu |
890ddd |
bool slowContains(const TRegion::Imp &r) const;
|
|
Toshihiro Shimizu |
890ddd |
bool contains(const TStroke &s, bool mayIntersect) const;
|
|
Toshihiro Shimizu |
890ddd |
bool isSubRegionOf(const TRegion::Imp &r) const;
|
|
Toshihiro Shimizu |
890ddd |
bool getInternalPoint(TPointD &p, double left, double right, double y);
|
|
Toshihiro Shimizu |
890ddd |
void computeScanlineIntersections(double y, vector<double> &intersections) const;</double>
|
|
Toshihiro Shimizu |
890ddd |
bool thereAreintersections(const TStroke &s) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int leftScanlineIntersections(const TPointD &p,
|
|
Toshihiro Shimizu |
890ddd |
double(TPointD::*h), double(TPointD::*v)) const;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegion *TRegion::findRegion(const TRegion &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(r.getBBox(), getBBox(), 1e-3))
|
|
Toshihiro Shimizu |
890ddd |
return (TRegion *)this;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!getBBox().contains(r.getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
TRegion *ret;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if ((ret = m_imp->m_includedRegionArray[i]->findRegion(r)) != 0)
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegion::TRegion()
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new TRegion::Imp())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//m_imp->m_fillStyle->setRegion(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegion::~TRegion()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::contains(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool leftIntersectionsAreOdd=false, rightIntersectionsAreOdd=false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!getBBox().contains(p))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tpointd> poly;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
UINT i=0 ;
|
|
Toshihiro Shimizu |
890ddd |
//region2polyline(poly, *this);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for(; i
|
|
Toshihiro Shimizu |
890ddd |
stroke2polyline( poly, *m_edge[i]->m_s, 1.0, m_edge[i]->m_w0, m_edge[i]->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
poly.push_back(poly.front());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double dist = (bbox.x1-bbox.x0)*0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment horizSegment = TSegment(TPointD(bbox.x0-dist, p.y),TPointD(bbox.x1+dist, p.y));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair> intersections;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (poly[i].y==poly[i+1].y && poly[i+1].y==p.y)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (intersect(TSegment(poly[i], poly[i+1]), horizSegment,
|
|
Toshihiro Shimizu |
890ddd |
intersections))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(intersections.size()==1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD pInt = horizSegment.getPoint(intersections[0].second);
|
|
Toshihiro Shimizu |
890ddd |
if (pInt==poly[i+1])
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
if (pInt.x>p.x)
|
|
Toshihiro Shimizu |
890ddd |
rightIntersectionsAreOdd = !rightIntersectionsAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
leftIntersectionsAreOdd = !leftIntersectionsAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//assert(!(leftIntersectionsAreOdd^rightIntersectionsAreOdd)); //intersections must be even!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return leftIntersectionsAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//questa funzione fa l'intersezione della porzione [t0, t1) della quadratica q
|
|
Toshihiro Shimizu |
890ddd |
// con una retta orizzontale passante per p.y,
|
|
Toshihiro Shimizu |
890ddd |
//e setta i due booleani in base a quante intersezioni stanno a sx e a dx di p
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//il valore di ritorno dice se l'intersezione e' ad un estremo e se la curva
|
|
Toshihiro Shimizu |
890ddd |
//sta tutta sopra(1) o tutta sotto) -1;
|
|
Toshihiro Shimizu |
890ddd |
//questo valore viene riusato come input della successiva chiamata a findSide:
|
|
Toshihiro Shimizu |
890ddd |
//se anche questa ha l'intersezione allo stesso estremo e sullo stesso
|
|
Toshihiro Shimizu |
890ddd |
//lato (cuspide) quell'intersezione non conta(doppia, come con la tangente)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline int computeSide(const TQuadratic &q, double t, bool forward)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double speedY = q.getSpeedY(t);
|
|
Toshihiro Shimizu |
890ddd |
if (speedY == 0) //se la tangente e' zero, non si riesce a capire su che semipiano sta la curva rispetto alla semiretta orizzontale campione. in questo caso e' sufficiente vedere dove giace il terzo controlpoint della quad .
|
|
Toshihiro Shimizu |
890ddd |
speedY = (forward ? (q.getP2().y - q.getPoint(t).y) : (q.getPoint(t).y - q.getP0().y)); //q.getSpeedY(t+(forward?0.00001:-0.00001));
|
|
Toshihiro Shimizu |
890ddd |
return speedY > 0 ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline void computeIntersection(const TQuadratic &q, double t, double t0, double t1, double x, int sideOfPrevious, bool &leftAreOdd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (((t0 < t1 && t >= t0 && t < t1) || (t0 > t1 && t > t1 && t <= t0)) && q.getX(t) <= x) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t == t0) {
|
|
Toshihiro Shimizu |
890ddd |
assert(sideOfPrevious != 0);
|
|
Toshihiro Shimizu |
890ddd |
if (computeSide(q, t0, t0 < t1) != sideOfPrevious) //cuspide! non considero l'intersezione
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
leftAreOdd = !leftAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
__inline int findSides(const TPointD &p, const TQuadratic &q, double t0, double t1, bool &leftAreOdd, int sideOfPrevious)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = q.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//assert(!(t0==t1 && q.getPoint(t0).y==p.y));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (bbox.y0 > p.y || bbox.y1 < p.y)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t0 == t1)
|
|
Toshihiro Shimizu |
890ddd |
return sideOfPrevious;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double y0 = q.getP0().y;
|
|
Toshihiro Shimizu |
890ddd |
double y1 = q.getP1().y;
|
|
Toshihiro Shimizu |
890ddd |
double y2 = q.getP2().y;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* ottimizzazione....lenta.
|
|
Toshihiro Shimizu |
890ddd |
if((q.getPoint(t0).y-p.y)*(q.getPoint(t1).y-p.y)<0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if(bbox.x1
|
|
Toshihiro Shimizu |
890ddd |
else if(bbox.x0>p.x) {rightAreOdd = !rightAreOdd; return; }
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double det;
|
|
Toshihiro Shimizu |
890ddd |
double alfa = y0 - 2 * y1 + y2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!areAlmostEqual(alfa, 0, 1e-10)) //alfa, il coefficiente di t^2, non e' zero: due soluzioni
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
det = y1 * y1 - y0 * y2 + p.y * alfa;
|
|
Toshihiro Shimizu |
890ddd |
if (det < 0 || (det == 0 && y0 != p.y && y2 != p.y)) // con det<0 no soluzioni reali o due soluzioni coincidenti
|
|
Toshihiro Shimizu |
890ddd |
// (a meno che le soluzioni non siano agli estremi, in quel caso e'
|
|
Toshihiro Shimizu |
890ddd |
// una sola!), due intersezioni stesso lato, posso scartare
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
double ta, tb;
|
|
Toshihiro Shimizu |
890ddd |
det = sqrt(det);
|
|
Toshihiro Shimizu |
890ddd |
ta = tb = (y0 - y1 + det) / alfa;
|
|
Toshihiro Shimizu |
890ddd |
computeIntersection(q, ta, t0, t1, p.x, sideOfPrevious, leftAreOdd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (det != 0) {
|
|
Toshihiro Shimizu |
890ddd |
tb = (y0 - y1 - det) / alfa;
|
|
Toshihiro Shimizu |
890ddd |
computeIntersection(q, tb, t0, t1, p.x, sideOfPrevious, leftAreOdd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (ta == t1 || tb == t1)
|
|
Toshihiro Shimizu |
890ddd |
return computeSide(q, t1, t1 < t0); //q.getSpeedY(t1)>0?1:-1;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else //alfa, il coefficiente di t^2 e' zero: una sola soluzione
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (y2 == y0) //segmento orizzontale
|
|
Toshihiro Shimizu |
890ddd |
return sideOfPrevious;
|
|
Toshihiro Shimizu |
890ddd |
double t = (p.y - y0) / (y2 - y0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((t0 < t1 && t >= t0 && t < t1) || (t0 > t1 && t > t1 && t <= t0)) {
|
|
Toshihiro Shimizu |
890ddd |
if ((q.getP2().x - q.getP0().x) * t + q.getP0().x <= p.x) {
|
|
Toshihiro Shimizu |
890ddd |
leftAreOdd = !leftAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
if (t == t0) {
|
|
Toshihiro Shimizu |
890ddd |
assert(sideOfPrevious != 0);
|
|
Toshihiro Shimizu |
890ddd |
if (((y2 - y0 > 0) ? 1 : -1) != sideOfPrevious)
|
|
Toshihiro Shimizu |
890ddd |
leftAreOdd = !leftAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (t == t1)
|
|
Toshihiro Shimizu |
890ddd |
return (y2 - y0 > 0) ? 1 : -1; //q.getPoint(t0).y>p.y?1:-1;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void addIntersection(const TQuadratic &q, double t, double t0, double t1, vector<double> &intersections, double intersection, vector<int> &sides)</int></double>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int side = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(t, t0, 1e-4))
|
|
Toshihiro Shimizu |
890ddd |
side = (q.getPoint(t0 + ((t1 > t0) ? 0.01 : -0.01)).y - q.getPoint(t0).y) > 0 ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
else if (areAlmostEqual(t, t1, 1e-4))
|
|
Toshihiro Shimizu |
890ddd |
side = (q.getPoint(t1 + ((t0 > t1) ? 0.01 : -0.01)).y - q.getPoint(t1).y) > 0 ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!intersections.empty() && areAlmostEqual(intersection, intersections.back(), 1e-4)) {
|
|
Toshihiro Shimizu |
890ddd |
//assert(areAlmostEqual(t, t0, 1e-3));
|
|
Toshihiro Shimizu |
890ddd |
assert(sides.back() != 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (side == sides.back()) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
sides.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(intersection);
|
|
Toshihiro Shimizu |
890ddd |
sides.push_back(side);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void findIntersections(double y, const TQuadratic &q, double t0, double t1, vector<double> &intersections,</double>
|
|
Toshihiro Shimizu |
890ddd |
vector<int> &sides)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = q.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int side = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (t0 == t1 || bbox.y0 > y || bbox.y1 < y)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double y0 = q.getP0().y;
|
|
Toshihiro Shimizu |
890ddd |
double y1 = q.getP1().y;
|
|
Toshihiro Shimizu |
890ddd |
double y2 = q.getP2().y;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double alfa = y0 - 2 * y1 + y2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!areAlmostEqual(alfa, 0, 1e-10)) //la quadratica non e' un segmento
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double det = y1 * y1 - y0 * y2 + y * alfa;
|
|
Toshihiro Shimizu |
890ddd |
assert(det >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (det < 1e-6) // con det==0 soluzioni coincidenti
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double t = (y0 - y1) / alfa;
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(t, t0, 1e-5) || areAlmostEqual(t, t1, 1e-5)) {
|
|
Toshihiro Shimizu |
890ddd |
double s = 1 - t;
|
|
Toshihiro Shimizu |
890ddd |
double intersection = q.getP0().x * s * s + 2 * t * s * q.getP1().x + t * t * q.getP2().x;
|
|
Toshihiro Shimizu |
890ddd |
addIntersection(q, t, t0, t1, intersections, intersection, sides);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
double ta, tb;
|
|
Toshihiro Shimizu |
890ddd |
bool rev = q.getPoint(t0).x > q.getPoint(t1).x;
|
|
Toshihiro Shimizu |
890ddd |
//if (alfa<0) rev = !rev;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
det = sqrt(det);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ta = (y0 - y1 + det) / alfa;
|
|
Toshihiro Shimizu |
890ddd |
double sa = 1 - ta;
|
|
Toshihiro Shimizu |
890ddd |
double intersectiona = q.getP0().x * sa * sa + 2 * ta * sa * q.getP1().x + ta * ta * q.getP2().x;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tb = (y0 - y1 - det) / alfa;
|
|
Toshihiro Shimizu |
890ddd |
double sb = 1 - tb;
|
|
Toshihiro Shimizu |
890ddd |
double intersectionb = q.getP0().x * sb * sb + 2 * tb * sb * q.getP1().x + tb * tb * q.getP2().x;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((rev && intersectiona < intersectionb) || (!rev && intersectiona > intersectionb))
|
|
Toshihiro Shimizu |
890ddd |
tswap(intersectiona, intersectionb), tswap(ta, tb);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((t0 < t1 && ta >= t0 && ta <= t1) || (t0 >= t1 && ta >= t1 && ta <= t0))
|
|
Toshihiro Shimizu |
890ddd |
addIntersection(q, ta, t0, t1, intersections, intersectiona, sides);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((t0 < t1 && tb >= t0 && tb <= t1) || (t0 >= t1 && tb >= t1 && tb <= t0))
|
|
Toshihiro Shimizu |
890ddd |
addIntersection(q, tb, t0, t1, intersections, intersectionb, sides);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else if (y2 != y0) //la quadratica e' un segmento non orizzontale
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (y2 == y0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
double t = (y - y0) / (y2 - y0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!((t0 < t1 && t >= t0 && t <= t1) || (t0 >= t1 && t >= t1 && t <= t0)))
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double intersection = (q.getP2().x - q.getP0().x) * t + q.getP0().x;
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(t, t1, 1e-4))
|
|
Toshihiro Shimizu |
890ddd |
side = (q.getPoint(t0).y > q.getPoint(t1).y) ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
else if (areAlmostEqual(t, t0, 1e-4))
|
|
Toshihiro Shimizu |
890ddd |
side = (q.getPoint(t1).y > q.getPoint(t0).y) ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
if (!intersections.empty() && areAlmostEqual(intersection, intersections.back(), 1e-4)) {
|
|
Toshihiro Shimizu |
890ddd |
//assert(areAlmostEqual(t, t0, 1e-4));
|
|
Toshihiro Shimizu |
890ddd |
assert(sides.back() != 0);
|
|
Toshihiro Shimizu |
890ddd |
assert(side != 0);
|
|
Toshihiro Shimizu |
890ddd |
if (side == sides.back()) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
sides.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(intersection);
|
|
Toshihiro Shimizu |
890ddd |
sides.push_back(side);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} else //la quadratica e' un segmento orizzontale
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, TQuadratic(q.getPoint(t0), 0.5 * (q.getPoint(t0) + q.getPoint(t1)) + TPointD(0, 1.0), q.getPoint(t1)), 0, 1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::contains(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->contains(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::contains(const TStroke &s, bool mayIntersect) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->contains(s, mayIntersect);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::checkRegion()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->checkRegion();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::contains(const TRegion &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->contains(*r.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::getPointInside(TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getPointInside(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegionProp *TRegion::getProp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//if(m_working) buttato m_working
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
int styleId = getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if(!styleId ) return 0;
|
|
Toshihiro Shimizu |
890ddd |
TColorStyle * style = palette->getStyle(styleId);
|
|
Toshihiro Shimizu |
890ddd |
if (!style->isRegionStyle() || style->isEnabled() == false)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = style->makeRegionProp(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::setProp(TRegionProp *prop)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(prop);
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = prop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::draw(const TVectorRenderData &rd)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int styleId = getStyle();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if(!styleId )
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TColorStyle * style = rd.m_palette->getStyle(styleId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!style->isRegionStyle() || style->isEnabled() == false)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = style->makeRegionProp(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop->draw(rd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void checkPolyline(const vector<t3dpointd> &p)</t3dpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int ret;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (p.size() < 3)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD p1;
|
|
Toshihiro Shimizu |
890ddd |
TPointD p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int pointSize = (int)p.size() - 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < pointSize; i++) {
|
|
Toshihiro Shimizu |
890ddd |
for (int j = i + 1; j < pointSize; j++) {
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair> res;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p1 = TPointD(p[i].x, p[i].y);
|
|
Toshihiro Shimizu |
890ddd |
p2 = TPointD(p[i + 1].x, p[i + 1].y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment s0(p1, p2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p1 = TPointD(p[j].x, p[j].y);
|
|
Toshihiro Shimizu |
890ddd |
p2 = TPointD(p[j + 1].x, p[j + 1].y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment s1(p1, p2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ret = intersect(s0, s1, res);
|
|
Toshihiro Shimizu |
890ddd |
if (ret)
|
|
Toshihiro Shimizu |
890ddd |
assert(
|
|
Toshihiro Shimizu |
890ddd |
(ret == 1) &&
|
|
Toshihiro Shimizu |
890ddd |
(areAlmostEqual(res[0].first, 1) ||
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(res[0].first, 0)) &&
|
|
Toshihiro Shimizu |
890ddd |
(areAlmostEqual(res[0].second, 1) ||
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(res[0].second, 0)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p1 = TPointD(p.back().x, p.back().y);
|
|
Toshihiro Shimizu |
890ddd |
p2 = TPointD(p[0].x, p[0].y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment s0(p1, p2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int j = 0; j < pointSize; j++) {
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair> res;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p1 = TPointD(p[j].x, p[j].y);
|
|
Toshihiro Shimizu |
890ddd |
p2 = TPointD(p[j + 1].x, p[j + 1].y);
|
|
Toshihiro Shimizu |
890ddd |
TSegment s1(p1, p2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ret = intersect(s0, s1, res);
|
|
Toshihiro Shimizu |
890ddd |
if (ret)
|
|
Toshihiro Shimizu |
890ddd |
assert(
|
|
Toshihiro Shimizu |
890ddd |
(ret == 1) &&
|
|
Toshihiro Shimizu |
890ddd |
(areAlmostEqual(res[0].first, 1) ||
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(res[0].first, 0)) &&
|
|
Toshihiro Shimizu |
890ddd |
(areAlmostEqual(res[0].second, 1) ||
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(res[0].second, 0)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::getInternalPoint(TPointD &p, double left, double right, double y)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(left < right);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(left, right, 1e-2))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double mid = 0.5 * (left + right);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p = TPointD(mid, y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (noSubregionContains(p))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!getInternalPoint(p, left, mid, y))
|
|
Toshihiro Shimizu |
890ddd |
return getInternalPoint(p, mid, right, y);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::noSubregionContains(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (contains(p)) {
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < (int)m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_includedRegionArray[i]->contains(p))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::computeScanlineIntersections(double y, vector<double> &intersections) const</double>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeScanlineIntersections(y, intersections);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::Imp::computeScanlineIntersections(double y, vector<double> &intersections) const</double>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = getBBox();
|
|
Toshihiro Shimizu |
890ddd |
if (y <= bbox.y0 || y >= bbox.y1)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(intersections.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT i, firstSide = 0;
|
|
Toshihiro Shimizu |
890ddd |
vector<int> sides;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < m_edge.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = m_edge[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *s = e->m_s;
|
|
Toshihiro Shimizu |
890ddd |
if (s->getBBox().y0 > y || s->getBBox().y1 < y)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
int chunkIndex0, chunkIndex1;
|
|
Toshihiro Shimizu |
890ddd |
double t0, t1;
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(e->m_w0, chunkIndex0, t0);
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(e->m_w1, chunkIndex1, t1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkIndex0 > chunkIndex1) {
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(chunkIndex0), t0, 0, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(j), 1, 0, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(chunkIndex1), 1, t1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
} else if (chunkIndex0 < chunkIndex1) {
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(chunkIndex0), t0, 1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(j), 0, 1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(chunkIndex1), 0, t1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
findIntersections(y, *s->getChunk(chunkIndex0), t0, t1, intersections, sides);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (intersections.size() > 0 && intersections.front() == intersections.back()) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
if (!sides.empty() && sides.front() == sides.back() && intersections.size() > 0)
|
|
Toshihiro Shimizu |
890ddd |
intersections.erase(intersections.begin());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::sort(intersections.begin(), intersections.end());
|
|
Toshihiro Shimizu |
890ddd |
assert(intersections.size() % 2 == 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::contains(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool leftAreOdd = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!getBBox().contains(p))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//printContains(p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int side = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < m_edge.size() * 2; i++) //i pari, esplora gli edge,
|
|
Toshihiro Shimizu |
890ddd |
//i dispari esplora i segmenti di autoclose tra un edge e il successivo
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (i & 0x1) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD p0 = m_edge[i / 2]->m_s->getPoint(m_edge[i / 2]->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
TPointD p1;
|
|
Toshihiro Shimizu |
890ddd |
if (i / 2 < m_edge.size() - 1)
|
|
Toshihiro Shimizu |
890ddd |
p1 = m_edge[i / 2 + 1]->m_s->getPoint(m_edge[i / 2 + 1]->m_w0);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
p1 = m_edge[0]->m_s->getPoint(m_edge[0]->m_w0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tmin(p0.y, p1.y) > p.y || tmax(p0.y, p1.y) < p.y)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!areAlmostEqual(p0, p1, 1e-2))
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, TQuadratic(p0, 0.5 * (p0 + p1), p1), 0.0, 1.0, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = m_edge[i / 2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *s = e->m_s;
|
|
Toshihiro Shimizu |
890ddd |
if (s->getBBox().y0 > p.y || s->getBBox().y1 < p.y)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t0, t1;
|
|
Toshihiro Shimizu |
890ddd |
int chunkIndex0, chunkIndex1;
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q0, *q1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(e->m_w0, chunkIndex0, t0);
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(e->m_w1, chunkIndex1, t1);
|
|
Toshihiro Shimizu |
890ddd |
q0 = s->getChunk(chunkIndex0);
|
|
Toshihiro Shimizu |
890ddd |
q1 = s->getChunk(chunkIndex1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (i == 0 && areAlmostEqual(q0->getPoint(t0).y, p.y)) {
|
|
Toshihiro Shimizu |
890ddd |
double tEnd;
|
|
Toshihiro Shimizu |
890ddd |
int chunkIndexEnd;
|
|
Toshihiro Shimizu |
890ddd |
TEdge *edgeEnd = m_edge.back();
|
|
Toshihiro Shimizu |
890ddd |
edgeEnd->m_s->getChunkAndT(edgeEnd->m_w1, chunkIndexEnd, tEnd);
|
|
Toshihiro Shimizu |
890ddd |
assert(areAlmostEqual(edgeEnd->m_s->getChunk(chunkIndexEnd)->getPoint(tEnd).y, p.y));
|
|
Toshihiro Shimizu |
890ddd |
side = edgeEnd->m_s->getChunk(chunkIndexEnd)->getSpeed(tEnd).y > 0 ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkIndex0 != chunkIndex1) {
|
|
Toshihiro Shimizu |
890ddd |
/*if (chunkIndex0>chunkIndex1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
tswap(chunkIndex0, chunkIndex1);
|
|
Toshihiro Shimizu |
890ddd |
tswap(t0, t1);
|
|
Toshihiro Shimizu |
890ddd |
}*/
|
|
Toshihiro Shimizu |
890ddd |
if (chunkIndex0 > chunkIndex1) {
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *q0, t0, 0, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *s->getChunk(j), 1, 0, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *q1, 1, t1, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *q0, t0, 1, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *s->getChunk(j), 0, 1, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *q1, 0, t1, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
side = findSides(p, *q0, t0, t1, leftAreOdd, side);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (i & 0x1)
|
|
Toshihiro Shimizu |
890ddd |
delete q0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return leftAreOdd;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TRegion::Imp::leftScanlineIntersections(
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &p,
|
|
Toshihiro Shimizu |
890ddd |
double(TPointD::*h), double(TPointD::*v)) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
struct Locals {
|
|
Toshihiro Shimizu |
890ddd |
const Imp *m_this;
|
|
Toshihiro Shimizu |
890ddd |
double m_x, m_y,
|
|
Toshihiro Shimizu |
890ddd |
m_tol;
|
|
Toshihiro Shimizu |
890ddd |
double TPointD::*m_h,
|
|
Toshihiro Shimizu |
890ddd |
TPointD::*m_v;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline double x(const TPointD &p) const { return p.*m_h; }
|
|
Toshihiro Shimizu |
890ddd |
inline double y(const TPointD &p) const { return p.*m_v; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline double get(const TQuadratic &q, double t, double(TPointD::*val)) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double one_t = 1.0 - t;
|
|
Toshihiro Shimizu |
890ddd |
return one_t * (one_t * q.getP0().*val + t * q.getP1().*val) + t * (one_t * q.getP1().*val + t * q.getP2().*val);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline double getX(const TQuadratic &q, double t) const { return get(q, t, m_h); }
|
|
Toshihiro Shimizu |
890ddd |
inline double getY(const TQuadratic &q, double t) const { return get(q, t, m_v); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void getEdgeData(int e, TEdge *&ed, TStroke *&s,
|
|
Toshihiro Shimizu |
890ddd |
int &chunk0, const TThickQuadratic *&q0, double &t0,
|
|
Toshihiro Shimizu |
890ddd |
int &chunk1, const TThickQuadratic *&q1, double &t1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ed = m_this->m_edge[e];
|
|
Toshihiro Shimizu |
890ddd |
s = ed->m_s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(ed->m_w0, chunk0, t0);
|
|
Toshihiro Shimizu |
890ddd |
s->getChunkAndT(ed->m_w1, chunk1, t1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
q0 = s->getChunk(chunk0);
|
|
Toshihiro Shimizu |
890ddd |
q1 = s->getChunk(chunk1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool isInYRange(double y0, double y1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return (y0 <= m_y && m_y < y1) // Assuming the first endpoint is vertical-including,
|
|
Toshihiro Shimizu |
890ddd |
|| (y1 < m_y && m_y <= y0); // while the latter is not. Vertical conditions are EXACT.
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool areInYRange(const TQuadratic &q, double t0, double t1,
|
|
Toshihiro Shimizu |
890ddd |
int(&solIdx)[2]) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(0.0 <= t0 && t0 <= 1.0), assert(0.0 <= t1 && t1 <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double der[2] = {y(p1) - y(p0), y(p0) - y(p1) + y(p2) - y(p1)},
|
|
Toshihiro Shimizu |
890ddd |
s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double y0 = getY(q, t0), y1 = getY(q, t1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tcg::poly_ops::solve_1(der, &s, m_tol)) {
|
|
Toshihiro Shimizu |
890ddd |
if (t0 <= s && s < t1) {
|
|
Toshihiro Shimizu |
890ddd |
double ys = getY(q, s);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
solIdx[0] = (ys < m_y && m_y <= y0 || y0 <= m_y && m_y < ys) ? 0 : -1;
|
|
Toshihiro Shimizu |
890ddd |
solIdx[1] = (ys < m_y && m_y < y1 || y1 < m_y && m_y < ys) ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
} else if (t1 < s && s <= t0) {
|
|
Toshihiro Shimizu |
890ddd |
double ys = getY(q, s);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
solIdx[0] = (ys < m_y && m_y <= y0 || y0 <= m_y && m_y < ys) ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
solIdx[1] = (ys < m_y && m_y < y1 || y1 < m_y && m_y < ys) ? 0 : -1;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
solIdx[0] = isInYRange(y0, y1) ? (t0 < s) ? 0 : 1
|
|
Toshihiro Shimizu |
890ddd |
: -1;
|
|
Toshihiro Shimizu |
890ddd |
solIdx[1] = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
solIdx[1] = solIdx[0] = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return (solIdx[0] >= 0 || solIdx[1] >= 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int leftScanlineIntersections(const TSegment &seg, bool &ascending)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &p0 = seg.getP0(), &p1 = seg.getP1();
|
|
Toshihiro Shimizu |
890ddd |
bool wasAscending = ascending;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ascending = (y(p1) > y(p0)) ? true
|
|
Toshihiro Shimizu |
890ddd |
: (y(p1) < y(p0)) ? false
|
|
Toshihiro Shimizu |
890ddd |
: (wasAscending = !ascending, ascending); // Couples with the cusp check below
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isInYRange(y(p0), y(p1)))
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_y == y(p0))
|
|
Toshihiro Shimizu |
890ddd |
return int(x(p0) < m_x && ascending == wasAscending); // Cusps treated here
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double y1_y0 = y(p1) - y(p0), // (x, m_y) in (p0, p1) from here on
|
|
Toshihiro Shimizu |
890ddd |
poly[2] = {(m_y - y(p0)) * (x(p1) - x(p0)), -y1_y0},
|
|
Toshihiro Shimizu |
890ddd |
sx_x0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return tcg::poly_ops::solve_1(poly, &sx_x0, m_tol) ? int(sx_x0 < m_x - x(p0))
|
|
Toshihiro Shimizu |
890ddd |
: int(x(p0) < m_x && x(p1) < m_x); // Almost horizontal segments are
|
|
Toshihiro Shimizu |
890ddd |
} // flattened along the axes
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int isAscending(const TThickQuadratic &q, double t, bool forward)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double y0 = y(q.getP0()), y1 = y(q.getP1()), y2 = y(q.getP2()),
|
|
Toshihiro Shimizu |
890ddd |
y1_y0 = y1 - y0, y2_y1 = y2 - y1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double yspeed_2 = tcg::numeric_ops::lerp(y1_y0, y2_y1, t) * (2 * int(forward) - 1),
|
|
Toshihiro Shimizu |
890ddd |
yaccel = y2_y1 - y1_y0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return (yspeed_2 > 0.0) ? 1
|
|
Toshihiro Shimizu |
890ddd |
: (yspeed_2 < 0.0) ? -1
|
|
Toshihiro Shimizu |
890ddd |
: tcg::numeric_ops::sign(yaccel);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int leftScanlineIntersections(const TQuadratic &q, double t0, double t1,
|
|
Toshihiro Shimizu |
890ddd |
bool &ascending)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double y1_y0 = y(p1) - y(p0),
|
|
Toshihiro Shimizu |
890ddd |
accel = y(p2) - y(p1) - y1_y0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Fallback to segment case whenever we have too flat quads
|
|
Toshihiro Shimizu |
890ddd |
if (std::fabs(accel) < m_tol)
|
|
Toshihiro Shimizu |
890ddd |
return leftScanlineIntersections(TSegment(q.getPoint(t0), q.getPoint(t1)), ascending);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Calculate new ascension
|
|
Toshihiro Shimizu |
890ddd |
int ascends = isAscending(q, t1, t0 < t1);
|
|
Toshihiro Shimizu |
890ddd |
bool wasAscending = ascending;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ascending = (ascends > 0) ? true
|
|
Toshihiro Shimizu |
890ddd |
: (ascends < 0) ? false
|
|
Toshihiro Shimizu |
890ddd |
: (wasAscending = !ascending, ascending); // Couples with the cusps check below
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// In case the y coords are not in range, quit
|
|
Toshihiro Shimizu |
890ddd |
int solIdx[2];
|
|
Toshihiro Shimizu |
890ddd |
if (!areInYRange(q, t0, t1, solIdx))
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Identify coordinates for which q(t) == y
|
|
Toshihiro Shimizu |
890ddd |
double poly[3] = {y(p0) - m_y, 2.0 * y1_y0, accel},
|
|
Toshihiro Shimizu |
890ddd |
s[2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int sCount = tcg::poly_ops::solve_2(poly, s); // Tolerance dealt at the first bailout above
|
|
Toshihiro Shimizu |
890ddd |
if (sCount == 2) {
|
|
Toshihiro Shimizu |
890ddd |
// Calculate result
|
|
Toshihiro Shimizu |
890ddd |
int result = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (solIdx[0] >= 0) {
|
|
Toshihiro Shimizu |
890ddd |
result += int(getX(q, s[solIdx[0]]) < m_x && (getY(q, t0) != m_y || ascending == wasAscending)); // Cusp check
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (solIdx[1] >= 0)
|
|
Toshihiro Shimizu |
890ddd |
result += int(getX(q, s[solIdx[1]]) < m_x);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return (assert(sCount == 0), 0); // Should never happen, since m_y is in range. If it ever happens,
|
|
Toshihiro Shimizu |
890ddd |
// it must be close to the extremal - so quit with no intersections.
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} locals = {this, p.*h, p.*v, 1e-4, h, v};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *ed;
|
|
Toshihiro Shimizu |
890ddd |
TStroke *s;
|
|
Toshihiro Shimizu |
890ddd |
int chunk0, chunk1;
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q0, *q1;
|
|
Toshihiro Shimizu |
890ddd |
double t0, t1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT e, eCount = m_edge.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int leftInters = 0;
|
|
Toshihiro Shimizu |
890ddd |
bool ascending = (locals.getEdgeData(eCount - 1, ed, s, chunk0, q0, t0, chunk1, q1, t1),
|
|
Toshihiro Shimizu |
890ddd |
locals.isAscending(*q1, t1, (t0 < t1)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (e = 0; e != eCount; ++e) {
|
|
Toshihiro Shimizu |
890ddd |
// Explore current edge
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Retrieve edge data
|
|
Toshihiro Shimizu |
890ddd |
locals.getEdgeData(e, ed, s, chunk0, q0, t0, chunk1, q1, t1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Compare edge against scanline segment
|
|
Toshihiro Shimizu |
890ddd |
if (chunk0 != chunk1) {
|
|
Toshihiro Shimizu |
890ddd |
if (chunk0 < chunk1) {
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*q0, t0, 1.0, ascending);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int c = chunk0 + 1; c != chunk1; ++c)
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 0.0, 1.0, ascending);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*q1, 0.0, t1, ascending);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*q0, t0, 0.0, ascending);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int c = chunk0 - 1; c != chunk1; --c)
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 1.0, 0.0, ascending);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*q1, 1.0, t1, ascending);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(*q0, t0, t1, ascending);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Explore autoclose segment at the end of current edge
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int nextE = (e + 1) % int(m_edge.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &p0 = m_edge[e]->m_s->getPoint(m_edge[e]->m_w1),
|
|
Toshihiro Shimizu |
890ddd |
&p1 = m_edge[nextE]->m_s->getPoint(m_edge[nextE]->m_w0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
leftInters += locals.leftScanlineIntersections(TSegment(p0, p1), ascending);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return leftInters;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TRegion::scanlineIntersectionsBefore(double x, double y, bool horizontal) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
static double TPointD::*const dir[2] = {&TPointD::x, &TPointD::y};
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->leftScanlineIntersections(TPointD(x, y), dir[!horizontal], dir[horizontal]);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::contains(const TEdge &e) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_edge.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if (*m_imp->m_edge[i] == e)
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Una regione contiene un'altra se non hanno strokes in comune e un qualsiasi punto
|
|
Toshihiro Shimizu |
890ddd |
// della seconda e' contenuto nella prima.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::contains(const TRegion::Imp &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!getBBox().contains(r.getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < r.m_edge.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < m_edge.size(); j++)
|
|
Toshihiro Shimizu |
890ddd |
if (*r.m_edge[i] == *m_edge[j])
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
// nessuno stroke in comune!!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
for ( i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = r.m_edge[i];
|
|
Toshihiro Shimizu |
890ddd |
if (!contains(e->m_s->getThickPoint(e->m_w0)))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
if (!contains(e->m_s->getThickPoint((e->m_w0+e->m_w1)/2.0)))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
if (!contains(e->m_s->getThickPoint(e->m_w1)))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = r.m_edge[0];
|
|
Toshihiro Shimizu |
890ddd |
return contains(e->m_s->getThickPoint((e->m_w0 + e->m_w1) / 2.0));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::thereAreintersections(const TStroke &s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_edge.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> dummy;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
if (intersect(m_edge[i]->m_s, &s, dummy, true))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::contains(const TStroke &s, bool mayIntersect) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!getBBox().contains(s.getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
if (mayIntersect && thereAreintersections(s))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return contains(s.getThickPoint(0.5));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::isSubRegionOf(const TRegion &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->isSubRegionOf(*r.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::isSubRegionOf(const TRegion::Imp &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT i, j;
|
|
Toshihiro Shimizu |
890ddd |
bool found, areTouching=false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!r.getBBox().contains(getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (j=0, found=false; !found && j
|
|
Toshihiro Shimizu |
890ddd |
if (m_edge[i]->m_s==r.m_edge[j]->m_s)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double w0 = tmin(m_edge[i]->m_w0, m_edge[i]->m_w1) ;
|
|
Toshihiro Shimizu |
890ddd |
double w1 = tmax(m_edge[i]->m_w0, m_edge[i]->m_w1) ;
|
|
Toshihiro Shimizu |
890ddd |
double r_w0 = tmin(r.m_edge[j]->m_w0, r.m_edge[j]->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
double r_w1 = tmax(r.m_edge[j]->m_w0, r.m_edge[j]->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((w0>=r_w0 || areAlmostEqual(w0, r_w0, 0.1)) &&
|
|
Toshihiro Shimizu |
890ddd |
(w1<=r_w1 || areAlmostEqual(w1, r_w1, 0.1)))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
found=true;
|
|
Toshihiro Shimizu |
890ddd |
areTouching = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
found=false;
|
|
Toshihiro Shimizu |
890ddd |
//found=true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if ((!found) && !r.contains(m_edge[i]->m_s->getPoint(0.5*(m_edge[i]->m_w0+m_edge[i]->m_w1))))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return areTouching;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::Imp::isSubRegionOf(const TRegion::Imp &r) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!r.getBBox().contains(getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_edge.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < r.m_edge.size(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e = r.m_edge[j];
|
|
Toshihiro Shimizu |
890ddd |
TEdge *subE = m_edge[i];
|
|
Toshihiro Shimizu |
890ddd |
if (subE->m_index == e->m_index &&
|
|
Toshihiro Shimizu |
890ddd |
(subE->m_w0 < m_edge[i]->m_w1) == (e->m_w0 < e->m_w1)) {
|
|
Toshihiro Shimizu |
890ddd |
bool forward = (e->m_w0 < e->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (forward && (subE->m_w0 >= e->m_w0 || areAlmostEqual(subE->m_w0, e->m_w0, 1e-3)) &&
|
|
Toshihiro Shimizu |
890ddd |
(subE->m_w1 <= e->m_w1 || areAlmostEqual(subE->m_w1, e->m_w1, 1e-3)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!forward && (subE->m_w0 <= e->m_w0 || areAlmostEqual(subE->m_w0, e->m_w0, 1e-3)) &&
|
|
Toshihiro Shimizu |
890ddd |
(subE->m_w1 >= e->m_w1 || areAlmostEqual(subE->m_w1, e->m_w1, 1e-3)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
TRegion *TRegion::getRegion(const TPointD &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_includedRegionArray[i]->contains(p))
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_includedRegionArray[i]->getRegion(p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::getInternalPoint(TPointD &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getInternalPoint(p, getBBox().x0, getBBox().x1, 0.5 * (getBBox().y0 + getBBox().y1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TRegion::fill(const TPointD &p, int styleId)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < m_imp->m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_includedRegionArray[i]->contains(p))
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_includedRegionArray[i]->fill(p, styleId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int ret = getStyle();
|
|
Toshihiro Shimizu |
890ddd |
setStyle(styleId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TRegion::selectFill(const TRectD &selArea, int styleId)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool hitSomeRegions = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (selArea.contains(getBBox())) {
|
|
Toshihiro Shimizu |
890ddd |
hitSomeRegions = true;
|
|
Toshihiro Shimizu |
890ddd |
setStyle(styleId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int regNum = m_imp->m_includedRegionArray.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < regNum; i++)
|
|
Toshihiro Shimizu |
890ddd |
hitSomeRegions |= m_imp->m_includedRegionArray[i]->selectFill(selArea, styleId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return hitSomeRegions;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::invalidateBBox()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->invalidateBBox();
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_includedRegionArray[i]->invalidateBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TRectD TRegion::getBBox(vector<trectd>& bboxReg,vector<tpointd>& intersPoint) const</tpointd></trectd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getBBox(bboxReg,intersPoint);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD TRegion::getBBox() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::addEdge(TEdge *e, bool minimizeEdges)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (minimizeEdges &&
|
|
Toshihiro Shimizu |
890ddd |
e->m_s->getMaxThickness() > 0.0 && //outline strokes ignore this
|
|
Toshihiro Shimizu |
890ddd |
!m_imp->m_edge.empty() &&
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_edge.back()->m_index == e->m_index &&
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(m_imp->m_edge.back()->m_w1, e->m_w0, 1e-5))
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_edge.back()->m_w1 = e->m_w1;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_edge.push_back(e);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValidBBox = false;
|
|
Toshihiro Shimizu |
890ddd |
//if (e->m_s->isSelfLoop())
|
|
Toshihiro Shimizu |
890ddd |
// assert(m_imp->m_edge.size()==1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *TRegion::getLastEdge() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_edge.empty())
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_edge.back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *TRegion::popBackEdge()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge *ret;
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_edge.empty())
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ret = m_imp->m_edge.back();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_edge.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *TRegion::popFrontEdge()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge *ret;
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_edge.empty())
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ret = m_imp->m_edge.front();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_edge.erase(m_imp->m_edge.begin());
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEdge *TRegion::getEdge(UINT index) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_edge[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT TRegion::getEdgeCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_edge.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegion *TRegion::getSubregion(UINT index) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_includedRegionArray[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT TRegion::getSubregionCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_includedRegionArray.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::deleteSubregion(UINT index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(m_imp->m_includedRegionArray[index]->getSubregionCount() == 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//delete m_imp->m_includedRegionArray[index];
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_includedRegionArray.erase(m_imp->m_includedRegionArray.begin() + index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::moveSubregionsTo(TRegion *r)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
while (m_imp->m_includedRegionArray.size()) {
|
|
Toshihiro Shimizu |
890ddd |
r->m_imp->m_includedRegionArray.push_back(m_imp->m_includedRegionArray.back());
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_includedRegionArray.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::Imp::printContains(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::ofstream of("C:\\temp\\region.txt");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
of << "point: " << p.x << " " << p.y << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < (UINT)m_edge.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < (UINT)m_edge[i]->m_s->getChunkCount(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q = m_edge[i]->m_s->getChunk(j);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
of << "******quad # " << j << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
of << " p0 " << q->getP0() << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
of << " p1 " << q->getP1() << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
of << " p2 " << q->getP2() << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
of << "****** " << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
of << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::print()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::cout << "\nNum edges: " << getEdgeCount() << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < getEdgeCount(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
std::cout << "\nEdge #" << i;
|
|
Toshihiro Shimizu |
890ddd |
std::cout << ":P0(" << getEdge(i)->m_s->getChunk(0)->getP0().x << "," << getEdge(i)->m_s->getChunk(0)->getP0().y << ")";
|
|
Toshihiro Shimizu |
890ddd |
std::cout << ":P2(" << getEdge(i)->m_s->getChunk(getEdge(i)->m_s->getChunkCount() - 1)->getP2().x << "," << getEdge(i)->m_s->getChunk(getEdge(i)->m_s->getChunkCount() - 1)->getP2().y << ")";
|
|
Toshihiro Shimizu |
890ddd |
std::cout << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_includedRegionArray.size()) {
|
|
Toshihiro Shimizu |
890ddd |
std::cout << "***** questa regione contiene:" << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_includedRegionArray[i]->print();
|
|
Toshihiro Shimizu |
890ddd |
std::cout << "***** fine" << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::setStyle(int colorStyle)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < getEdgeCount(); i++)
|
|
Toshihiro Shimizu |
890ddd |
getEdge(i)->setStyle(colorStyle);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (!colorStyle || (colorStyle && colorStyle->isFillStyle()) )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
getEdge(i)->setColorStyle(colorStyle);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRegionId TRegion::getId()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(getEdgeCount() > 0);
|
|
Toshihiro Shimizu |
890ddd |
TEdge *edge;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_edge.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_edge[i]->m_index >= 0) {
|
|
Toshihiro Shimizu |
890ddd |
edge = m_imp->m_edge[i];
|
|
Toshihiro Shimizu |
890ddd |
return TRegionId(edge->m_s->getId(),
|
|
Toshihiro Shimizu |
890ddd |
(float)((edge->m_w0 + edge->m_w1) * 0.5), edge->m_w0 < edge->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
edge = m_imp->m_edge[0];
|
|
Toshihiro Shimizu |
890ddd |
return TRegionId(edge->m_s->getId(),
|
|
Toshihiro Shimizu |
890ddd |
(float)((edge->m_w0 + edge->m_w1) * 0.5), edge->m_w0 < edge->m_w1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::invalidateProp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_prop)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop->notifyRegionChange();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TRegion::getStyle() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int ret = 0;
|
|
Toshihiro Shimizu |
890ddd |
UINT i = 0, j, n = getEdgeCount();
|
|
Toshihiro Shimizu |
890ddd |
for (; i < n; i++) {
|
|
Toshihiro Shimizu |
890ddd |
int styleId = getEdge(i)->getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if (styleId != 0 && ret == 0) {
|
|
Toshihiro Shimizu |
890ddd |
//assert(styleId<100);
|
|
Toshihiro Shimizu |
890ddd |
ret = styleId;
|
|
Toshihiro Shimizu |
890ddd |
if (i > 0)
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < i; j++)
|
|
Toshihiro Shimizu |
890ddd |
getEdge(i)->setStyle(ret);
|
|
Toshihiro Shimizu |
890ddd |
} else if (styleId != ret)
|
|
Toshihiro Shimizu |
890ddd |
getEdge(i)->setStyle(ret);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::addSubregion(TRegion *region)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->addSubregion(region);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRegion::Imp::addSubregion(TRegion *region)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (vector<tregion *="">::iterator it = m_includedRegionArray.begin(); it != m_includedRegionArray.end(); ++it) {</tregion>
|
|
Toshihiro Shimizu |
890ddd |
if (region->contains(**it)) {
|
|
Toshihiro Shimizu |
890ddd |
//region->addSubregion(*it);
|
|
Toshihiro Shimizu |
890ddd |
region->addSubregion(*it);
|
|
Toshihiro Shimizu |
890ddd |
it = m_includedRegionArray.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
while (it != m_includedRegionArray.end()) {
|
|
Toshihiro Shimizu |
890ddd |
if (region->contains(**it)) {
|
|
Toshihiro Shimizu |
890ddd |
region->addSubregion(*it);
|
|
Toshihiro Shimizu |
890ddd |
//region->addSubregion(*it);
|
|
Toshihiro Shimizu |
890ddd |
it = m_includedRegionArray.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
it++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_includedRegionArray.push_back(region);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
} else if ((*it)->contains(*region)) {
|
|
Toshihiro Shimizu |
890ddd |
(*it)->addSubregion(region);
|
|
Toshihiro Shimizu |
890ddd |
//(*it)->addSubregion(region);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_includedRegionArray.push_back(region);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// End Of File
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|