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