|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tmachine.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmathutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstrokeutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstrokeoutline.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tbezier.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tzerofinder.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurveutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <limits></limits>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define USE_NEW_3D_ERROR_COMPUTE 1
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace TConsts;
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef std::vector<double> DoubleArray;</double>
|
|
Toshihiro Shimizu |
890ddd |
typedef DoubleArray::iterator DoubleIt;
|
|
Toshihiro Shimizu |
890ddd |
typedef std::vector<tthickquadratic *=""> QuadStrokeChunkArray;</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static int numSaved = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void detectCorners(const std::vector<t3dpointd> &points,</t3dpointd>
|
|
Toshihiro Shimizu |
890ddd |
int minSampleNum,
|
|
Toshihiro Shimizu |
890ddd |
int minDist,
|
|
Toshihiro Shimizu |
890ddd |
int maxDist,
|
|
Toshihiro Shimizu |
890ddd |
double maxAngle,
|
|
Toshihiro Shimizu |
890ddd |
std::vector<int> &corners);</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void extractStrokeControlPoints(const QuadStrokeChunkArray &curves,
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> &ctrlPnts)</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *prev = curves[0];
|
|
Toshihiro Shimizu |
890ddd |
assert(prev);
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *curr;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ctrlPnts.push_back(prev->getThickP0());
|
|
Toshihiro Shimizu |
890ddd |
ctrlPnts.push_back(prev->getThickP1());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 1; i < curves.size(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
curr = curves[i];
|
|
Toshihiro Shimizu |
890ddd |
assert(curr);
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint middlePnt = (prev->getThickP2() + curr->getThickP0()) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
ctrlPnts.push_back(middlePnt);
|
|
Toshihiro Shimizu |
890ddd |
ctrlPnts.push_back(curr->getThickP1());
|
|
Toshihiro Shimizu |
890ddd |
prev = curr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ctrlPnts.push_back(prev->getThickP2());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline TThickPoint adapter(const TThickPoint &tp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return tp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline TThickPoint adapter(const TPointD &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return TThickPoint(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename t=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void buildChunksFromControlPoints(QuadStrokeChunkArray &tq,
|
|
Toshihiro Shimizu |
890ddd |
const vector<t> &v)</t>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *chunk;
|
|
Toshihiro Shimizu |
890ddd |
T temp;
|
|
Toshihiro Shimizu |
890ddd |
switch (v.size()) {
|
|
Toshihiro Shimizu |
890ddd |
case 0:
|
|
Toshihiro Shimizu |
890ddd |
tq.push_back(new TThickQuadratic);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
temp = adapter(v.front());
|
|
Toshihiro Shimizu |
890ddd |
chunk = new TThickQuadratic(temp, temp, temp);
|
|
Toshihiro Shimizu |
890ddd |
tq.push_back(chunk);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case 2: {
|
|
Toshihiro Shimizu |
890ddd |
TThickSegment s(adapter(v.front()), adapter(v.back()));
|
|
Toshihiro Shimizu |
890ddd |
chunk = new TThickQuadratic(s.getThickP0(), s.getThickPoint(0.5), s.getThickP1());
|
|
Toshihiro Shimizu |
890ddd |
tq.push_back(chunk);
|
|
Toshihiro Shimizu |
890ddd |
} break;
|
|
Toshihiro Shimizu |
890ddd |
default:
|
|
Toshihiro Shimizu |
890ddd |
assert(v.size() & 1);
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < v.size() - 1; i += 2) {
|
|
Toshihiro Shimizu |
890ddd |
chunk = new TThickQuadratic(adapter(v[i]), adapter(v[i + 1]), adapter(v[i + 2]));
|
|
Toshihiro Shimizu |
890ddd |
tq.push_back(chunk);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// WARNING duplicata in tellipticbrush
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// evitandone la gestione in tellip...
|
|
Toshihiro Shimizu |
890ddd |
inline bool pairValuesAreEqual(const DoublePair &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return p.first == p.second;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// WARNING duplicata in tellipticbrush
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// evitandone la gestione in tellip...
|
|
Toshihiro Shimizu |
890ddd |
void analyzeSolution(const vector<double> &coeff, vector<doublepair> &interval)</doublepair></double>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// risolve la disequazione coeff[2]*t^2 + coeff[1]*t + coeff[0] >= 0 in [0, 1] ritornando le soluzioni
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double> sol;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
rootFinding(coeff, sol);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(coeff[2])) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(coeff[1])) {
|
|
Toshihiro Shimizu |
890ddd |
if (coeff[0] >= 0)
|
|
Toshihiro Shimizu |
890ddd |
interval.push_back(DoublePair(0.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double singleSol = -coeff[0] / coeff[1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (coeff[1] > 0) {
|
|
Toshihiro Shimizu |
890ddd |
if (singleSol < 1)
|
|
Shinya Kitaoka |
12c444 |
interval.push_back(DoublePair(std::max(0.0, singleSol), 1.0));
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
if (singleSol > 0)
|
|
Shinya Kitaoka |
12c444 |
interval.push_back(DoublePair(0.0, std::min(1.0, singleSol)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//double delta = sq(coeff[1]) - 4*coeff[2]*coeff[0];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
sort(sol.begin(), sol.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (coeff[2] > 0) {
|
|
Toshihiro Shimizu |
890ddd |
switch (sol.size()) {
|
|
Toshihiro Shimizu |
890ddd |
case 0:
|
|
Toshihiro Shimizu |
890ddd |
interval.push_back(DoublePair(0.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
interval.push_back(DoublePair(0.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case 2:
|
|
Shinya Kitaoka |
12c444 |
interval.push_back(DoublePair(0.0, std::min(std::max(sol[0], 0.0), 1.0)));
|
|
Shinya Kitaoka |
12c444 |
interval.push_back(DoublePair(std::max(std::min(sol[1], 1.0), 0.0), 1.0));
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else if (coeff[2] < 0 && sol.size() == 2)
|
|
Shinya Kitaoka |
12c444 |
interval.push_back(DoublePair(std::min(std::max(sol[0], 0.0), 1.0),
|
|
Shinya Kitaoka |
12c444 |
std::max(std::min(sol[1], 1.0), 0.0)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair>::iterator it = std::remove_if(interval.begin(),</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
interval.end(),
|
|
Toshihiro Shimizu |
890ddd |
pairValuesAreEqual);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
interval.erase(it, interval.end());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void floorNegativeThickness(TThickQuadratic *quad)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(quad);
|
|
Toshihiro Shimizu |
890ddd |
double val = quad->getThickP0().thick;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (val < 0 && isAlmostZero(val))
|
|
Toshihiro Shimizu |
890ddd |
quad->setThickP0(TThickPoint(quad->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = quad->getThickP1().thick;
|
|
Toshihiro Shimizu |
890ddd |
if (val < 0 && isAlmostZero(val))
|
|
Toshihiro Shimizu |
890ddd |
quad->setThickP1(TThickPoint(quad->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
val = quad->getThickP2().thick;
|
|
Toshihiro Shimizu |
890ddd |
if (val < 0 && isAlmostZero(val))
|
|
Toshihiro Shimizu |
890ddd |
quad->setThickP2(TThickPoint(quad->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// potrebbe essere realizzata come unary function da usare in una transform
|
|
Toshihiro Shimizu |
890ddd |
void roundNegativeThickess(QuadStrokeChunkArray &v)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray
|
|
Toshihiro Shimizu |
890ddd |
protoStroke,
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ = 0,
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ_1 = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunkCount = v.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double> coeff;</double>
|
|
Toshihiro Shimizu |
890ddd |
double alpha,
|
|
Toshihiro Shimizu |
890ddd |
beta,
|
|
Toshihiro Shimizu |
890ddd |
gamma;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair></doublepair>
|
|
Toshihiro Shimizu |
890ddd |
positiveIntervals;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < chunkCount; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic &ttq = *v[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
alpha = ttq.getThickP0().thick - 2 * ttq.getThickP1().thick + ttq.getThickP2().thick;
|
|
Toshihiro Shimizu |
890ddd |
beta = 2.0 * (ttq.getThickP1().thick - ttq.getThickP0().thick);
|
|
Toshihiro Shimizu |
890ddd |
gamma = ttq.getThickP0().thick;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(gamma);
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(beta);
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(alpha);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// return sotto-intervalli non degeneri di [0, 1] in cui coeff[2]*t^2 + coeff[1]*t + coeff[0] >= 0
|
|
Toshihiro Shimizu |
890ddd |
analyzeSolution(coeff, positiveIntervals);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// il caso isAlmostZero(r(t)) per t in [0, 1] e' gestito direttamente da computeOutline
|
|
Toshihiro Shimizu |
890ddd |
switch (positiveIntervals.size()) {
|
|
Toshihiro Shimizu |
890ddd |
case 0: // r(t) <= 0 per t in [0, 1]
|
|
Toshihiro Shimizu |
890ddd |
tempTQ = new TThickQuadratic(ttq);
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP0(TThickPoint(tempTQ->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP1(TThickPoint(tempTQ->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP2(TThickPoint(tempTQ->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(tempTQ);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
if (positiveIntervals[0].first == 0.0 &&
|
|
Toshihiro Shimizu |
890ddd |
positiveIntervals[0].second == 1.0)
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(new TThickQuadratic(ttq));
|
|
Toshihiro Shimizu |
890ddd |
else if (positiveIntervals[0].first == 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
tempTQ = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
tempTQ_1 = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
ttq.split(positiveIntervals[0].first,
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ,
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ_1);
|
|
Toshihiro Shimizu |
890ddd |
tempTQ_1->setThickP0(TThickPoint(tempTQ_1->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ_1->setThickP1(TThickPoint(tempTQ_1->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ_1->setThickP2(TThickPoint(tempTQ_1->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
floorNegativeThickness(tempTQ);
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(tempTQ);
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(tempTQ_1);
|
|
Toshihiro Shimizu |
890ddd |
} else if (positiveIntervals[0].second == 1.0) {
|
|
Toshihiro Shimizu |
890ddd |
tempTQ = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
tempTQ_1 = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
ttq.split(positiveIntervals[0].first,
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ,
|
|
Toshihiro Shimizu |
890ddd |
*tempTQ_1);
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP0(TThickPoint(tempTQ->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP1(TThickPoint(tempTQ->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempTQ->setThickP2(TThickPoint(tempTQ->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(tempTQ);
|
|
Toshihiro Shimizu |
890ddd |
floorNegativeThickness(tempTQ_1);
|
|
Toshihiro Shimizu |
890ddd |
protoStroke.push_back(tempTQ_1);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
coeff.clear();
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(positiveIntervals[0].first);
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(positiveIntervals[0].second);
|
|
Toshihiro Shimizu |
890ddd |
split<tthickquadratic>(ttq, coeff, tempVectTQ);</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
assert(tempVectTQ.size() == 3);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[0]->setThickP0(TThickPoint(tempVectTQ[0]->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[0]->setThickP1(TThickPoint(tempVectTQ[0]->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[0]->setThickP2(TThickPoint(tempVectTQ[0]->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
floorNegativeThickness(tempVectTQ[1]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[2]->setThickP0(TThickPoint(tempVectTQ[2]->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[2]->setThickP1(TThickPoint(tempVectTQ[2]->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[2]->setThickP2(TThickPoint(tempVectTQ[2]->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
copy(tempVectTQ.begin(), tempVectTQ.end(), back_inserter(protoStroke));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case 2:
|
|
Toshihiro Shimizu |
890ddd |
assert(positiveIntervals[0].first == 0.0);
|
|
Toshihiro Shimizu |
890ddd |
assert(positiveIntervals[1].second == 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
coeff.clear();
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(positiveIntervals[0].second);
|
|
Toshihiro Shimizu |
890ddd |
coeff.push_back(positiveIntervals[1].first);
|
|
Toshihiro Shimizu |
890ddd |
split<tthickquadratic>(ttq, coeff, tempVectTQ);</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
assert(tempVectTQ.size() == 3);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
floorNegativeThickness(tempVectTQ[0]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[1]->setThickP0(TThickPoint(tempVectTQ[1]->getP0(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[1]->setThickP1(TThickPoint(tempVectTQ[1]->getP1(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ[1]->setThickP2(TThickPoint(tempVectTQ[1]->getP2(), 0.0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
floorNegativeThickness(tempVectTQ[2]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
copy(tempVectTQ.begin(), tempVectTQ.end(), back_inserter(protoStroke));
|
|
Toshihiro Shimizu |
890ddd |
tempVectTQ.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
positiveIntervals.clear();
|
|
Toshihiro Shimizu |
890ddd |
coeff.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
swap(protoStroke, v);
|
|
Toshihiro Shimizu |
890ddd |
clearPointerContainer(protoStroke);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// used in printContainer to set number of row to print
|
|
Toshihiro Shimizu |
890ddd |
const int MAX_ROW = 10;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline void changeTQDirection(TThickQuadratic *tq)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p = tq->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
tq->setThickP2(tq->getThickP0());
|
|
Toshihiro Shimizu |
890ddd |
tq->setThickP0(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double getTQDistance2(const TThickQuadratic& tq,
|
|
Toshihiro Shimizu |
890ddd |
const TPointD& p,
|
|
Toshihiro Shimizu |
890ddd |
double maxDistance2,
|
|
Toshihiro Shimizu |
890ddd |
double& currT)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRectD rect = tq.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
if (!rect.contains(p))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double dist21 = tdistance2(p, rect.getP00());
|
|
Toshihiro Shimizu |
890ddd |
double dist22 = tdistance2(p, rect.getP01());
|
|
Toshihiro Shimizu |
890ddd |
double dist23 = tdistance2(p, rect.getP10());
|
|
Toshihiro Shimizu |
890ddd |
double dist24 = tdistance2(p, rect.getP11());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
12c444 |
if (std::min(dist21, dist22, dist23, dist24)>=maxDistance2)
|
|
Toshihiro Shimizu |
890ddd |
return maxDistance2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
currT = tq.getT(p);
|
|
Toshihiro Shimizu |
890ddd |
double dist2 = tdistance2(tq.getPoint(currT), p);
|
|
Toshihiro Shimizu |
890ddd |
return (dist2
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" k,="" t=""> </class>
|
|
Toshihiro Shimizu |
890ddd |
void clearMap(std::map<k,t>& v)</k,t>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
typedef std::map<k,t>::iterator TypeIt;</k,t>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TypeIt it = v.begin();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for( ;it!=v.end(); ++it)
|
|
Toshihiro Shimizu |
890ddd |
delete it->second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
v.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Local binary function to find approx values in a vector.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
bool bfAreAlmostEqual(double x, double y)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double x_y = (x > y) ? x - y : y - x;
|
|
Toshihiro Shimizu |
890ddd |
return x_y < TConsts::epsilon;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Sends values of a container in standard input.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void printContainer(const T &c, int maxRow = MAX_ROW)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/* DA DECOMMENTARE SE NECESSARIO!!!!!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (maxRow <=0 ) maxRow = MAX_ROW;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typename T::const_iterator cit;
|
|
Toshihiro Shimizu |
890ddd |
cit = c.begin();
|
|
kogaki |
5bbc3c |
ostrstream oss1;
|
|
Toshihiro Shimizu |
890ddd |
oss1<<'['<
|
|
Toshihiro Shimizu |
890ddd |
TSystem::outputDebug( oss1.str() );
|
|
Toshihiro Shimizu |
890ddd |
oss1.freeze(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
for( ; cit != c.end(); ++cit)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
kogaki |
5bbc3c |
ostrstream oss;
|
|
Toshihiro Shimizu |
890ddd |
if( ++counter == maxRow-1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
oss<<'\n';
|
|
Toshihiro Shimizu |
890ddd |
counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
oss<<(*cit)<<'\n'<<'\0';
|
|
Toshihiro Shimizu |
890ddd |
TSystem::outputDebug( oss.str() );
|
|
Toshihiro Shimizu |
890ddd |
oss.freeze(false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void printContainer(ostream &os, const T &c, int maxRow = MAX_ROW)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (maxRow <= 0)
|
|
Toshihiro Shimizu |
890ddd |
maxRow = MAX_ROW;
|
|
Toshihiro Shimizu |
890ddd |
typename T::const_iterator cit;
|
|
Toshihiro Shimizu |
890ddd |
cit = c.begin();
|
|
Toshihiro Shimizu |
890ddd |
os << '[' << c.size() << ']' << "=\n";
|
|
Toshihiro Shimizu |
890ddd |
int counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (; cit != c.end(); ++cit) {
|
|
Toshihiro Shimizu |
890ddd |
if (++counter == maxRow - 1) {
|
|
Toshihiro Shimizu |
890ddd |
os << '\n';
|
|
Toshihiro Shimizu |
890ddd |
counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
os << (*cit) << ' ';
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void printContainerOfPointer(ostream &os, const T &c, int maxRow = MAX_ROW)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (maxRow <= 0)
|
|
Toshihiro Shimizu |
890ddd |
maxRow = MAX_ROW;
|
|
Toshihiro Shimizu |
890ddd |
typename T::const_iterator cit;
|
|
Toshihiro Shimizu |
890ddd |
cit = c.begin();
|
|
Toshihiro Shimizu |
890ddd |
os << '[' << c.size() << ']' << " - ";
|
|
Toshihiro Shimizu |
890ddd |
int counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (; cit != c.end(); ++cit) {
|
|
Toshihiro Shimizu |
890ddd |
if (++counter == maxRow - 1) {
|
|
Toshihiro Shimizu |
890ddd |
os << '\n';
|
|
Toshihiro Shimizu |
890ddd |
counter = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
os << **cit << ' ';
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Compute a proportion of type x:a=b:c
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Toshihiro Shimizu |
890ddd |
T proportion(T a, T b, T c)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(c != T(0));
|
|
Toshihiro Shimizu |
890ddd |
return a * b / c;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Compute a proportion of type x-off:a-off=b:c
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Toshihiro Shimizu |
890ddd |
T proportion(T a, T b, T c, T offset)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(c != T(0));
|
|
Toshihiro Shimizu |
890ddd |
return (a - offset) * b / c + offset;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
backinserter
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template
|
|
Toshihiro Shimizu |
890ddd |
typename container_>
|
|
Toshihiro Shimizu |
890ddd |
class TBackInserterPointer
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
container_ &m_c;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
explicit TBackInserterPointer(container_ &c)
|
|
Toshihiro Shimizu |
890ddd |
: m_c(c){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TBackInserterPointer &operator=(const type_ *value)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_c.push_back(new type_(*value));
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TBackInserterPointer &operator=(const type_ &value)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_c.push_back(new type_(value));
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
typedef type_ value_type;
|
|
Toshihiro Shimizu |
890ddd |
typedef type_ &reference;
|
|
Toshihiro Shimizu |
890ddd |
typedef type_ *pointer;
|
|
Toshihiro Shimizu |
890ddd |
typedef output_iterator_tag iterator_category;
|
|
Toshihiro Shimizu |
890ddd |
typedef ptrdiff_t difference_type;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TBackInserterPointer &operator*() { return *this; }
|
|
Toshihiro Shimizu |
890ddd |
TBackInserterPointer &operator++() { return *this; }
|
|
Toshihiro Shimizu |
890ddd |
TBackInserterPointer operator++(int val) { return *this; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TBackInserterPointer<tthickquadratic, quadstrokechunkarray=""> TThickQuadraticArrayInsertIterator;</tthickquadratic,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
simple adapter for find zero algorithm
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
struct computeOffset_ {
|
|
Toshihiro Shimizu |
890ddd |
TQuadraticLengthEvaluator m_lengthEval;
|
|
Toshihiro Shimizu |
890ddd |
double m_offset;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
computeOffset_(const TThickQuadratic *ttq,
|
|
Toshihiro Shimizu |
890ddd |
double offset)
|
|
Toshihiro Shimizu |
890ddd |
: m_lengthEval(*ttq), m_offset(offset)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double operator()(double par)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_lengthEval.getLengthAt(par) - m_offset;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
simple adapter for find zero algorithm
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
struct computeSpeed_ {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *ref_;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
computeSpeed_(const TThickQuadratic *ref)
|
|
Toshihiro Shimizu |
890ddd |
: ref_(ref)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double operator()(double par)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return norm(ref_->getSpeed(par));
|
|
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 |
const BYTE TStroke::c_selected_flag = 0x1;
|
|
Toshihiro Shimizu |
890ddd |
const BYTE TStroke::c_changed_region_flag = 0x2;
|
|
Toshihiro Shimizu |
890ddd |
const BYTE TStroke::c_dirty_flag = 0x4;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct TStroke::Imp {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
BYTE m_flag;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! This flag checks if changes occurs and if it is neccessary to update lenght.
|
|
Toshihiro Shimizu |
890ddd |
bool m_isValidLength;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! This flag checks if changes occurs and if it is neccessary to update outline.
|
|
Toshihiro Shimizu |
890ddd |
bool m_isOutlineValid;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_areDisabledComputeOfCaches;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD m_bBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! This vector contains length computed for each control point of stroke.
|
|
Toshihiro Shimizu |
890ddd |
DoubleArray m_partialLenghtArray;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! This vector contains parameter computed for each control point of stroke.
|
|
Toshihiro Shimizu |
890ddd |
DoubleArray m_parameterValueAtControlPoint;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray m_centerLineArray;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_selfLoop;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int m_negativeThicknessPoints;
|
|
Toshihiro Shimizu |
890ddd |
double m_averageThickness;
|
|
Toshihiro Shimizu |
890ddd |
double m_maxThickness;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int m_id;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
TStrokeProp *m_prop;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::OutlineOptions m_outlineOptions;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp(const vector<tpointd> &v);</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp(const vector<tthickpoint> &v);</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~Imp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_prop;
|
|
Toshihiro Shimizu |
890ddd |
clearPointerContainer(m_centerLineArray);
|
|
Toshihiro Shimizu |
890ddd |
//delete m_style;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void init();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline double getW(int index) { return ((int)m_parameterValueAtControlPoint.size() > index) ? m_parameterValueAtControlPoint[index] : m_parameterValueAtControlPoint.back(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD computeCenterlineBBox();
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
It computes the bounding box of the subStroke in the parameter range w0-w1.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void computeMaxThickness();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD computeSubBBox(double w0, double w1) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline QuadStrokeChunkArray &getTQArray()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_centerLineArray;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Swaps the geometrical infos only
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void swapGeometry(TStroke::Imp &other) throw();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void computeCacheVector();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Set value in m_parameterValueAtControlPoint
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void computeParameterInControlPoint();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Update parameter in m_parameterValueAtControlPoint
|
|
Toshihiro Shimizu |
890ddd |
after insert of control point in stroke.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void updateParameterValue(double w,
|
|
Toshihiro Shimizu |
890ddd |
UINT chunk,
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *tq1,
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *tq2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
From parameter w retrieves chunk and its parameter ( t in [0,1] ).
|
|
Toshihiro Shimizu |
890ddd |
Return
|
|
Toshihiro Shimizu |
890ddd |
true -> error (parameter w out of range, etc)
|
|
Toshihiro Shimizu |
890ddd |
false -> ok
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
bool retrieveChunkAndItsParamameter(double w, int &chunk, double &t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
From lenght s retrieves chunk and its parameter ( t in [0,1] ).
|
|
Toshihiro Shimizu |
890ddd |
Return
|
|
Toshihiro Shimizu |
890ddd |
true -> error (parameter w out of range, etc)
|
|
Toshihiro Shimizu |
890ddd |
false -> ok
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
bool retrieveChunkAndItsParamameterAtLength(double s, int &chunk, double &t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Retrieve chunk which contains the n-th control point of stroke.
|
|
Toshihiro Shimizu |
890ddd |
If control point is between two chunks return the left point.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
int retrieveChunkFromControlPointIndex(int n)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= n && n < getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (n & 1)
|
|
Toshihiro Shimizu |
890ddd |
++n;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
n >>= 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return n ? n - 1 : n;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Retrieve range for a chunk.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
DoublePair retrieveParametersFromChunk(UINT chunk)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
DoublePair outPar;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int nFirst, nSecond;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
nFirst = chunk * 2;
|
|
Toshihiro Shimizu |
890ddd |
nSecond = (chunk + 1) * 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
outPar.first = getW(nFirst);
|
|
Toshihiro Shimizu |
890ddd |
outPar.second = getW(nSecond);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return outPar;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void print(ostream &os);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline int getChunkCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_centerLineArray.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline int getControlPointCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT
|
|
Toshihiro Shimizu |
890ddd |
out = 2 * getChunkCount() + 1;
|
|
Toshihiro Shimizu |
890ddd |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *getChunk(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (0 <= index && index < getChunkCount())
|
|
Toshihiro Shimizu |
890ddd |
return m_centerLineArray[index];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Imp(const Imp &other);
|
|
Toshihiro Shimizu |
890ddd |
Imp &operator=(const Imp &other);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int maxStrokeId = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! init() is required to initialize all variable
|
|
Toshihiro Shimizu |
890ddd |
Call init after centerline initialization, because
|
|
Toshihiro Shimizu |
890ddd |
it's necessary to compute BBox
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::init()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_flag = c_dirty_flag;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_styleId = 1;
|
|
Toshihiro Shimizu |
890ddd |
m_prop = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_id = ++maxStrokeId;
|
|
Toshihiro Shimizu |
890ddd |
m_isValidLength = false;
|
|
Toshihiro Shimizu |
890ddd |
m_isOutlineValid = false;
|
|
Toshihiro Shimizu |
890ddd |
m_areDisabledComputeOfCaches = false;
|
|
Toshihiro Shimizu |
890ddd |
m_selfLoop = false;
|
|
Toshihiro Shimizu |
890ddd |
m_averageThickness = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_maxThickness = -1;
|
|
Toshihiro Shimizu |
890ddd |
m_negativeThicknessPoints = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < m_centerLineArray.size(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_centerLineArray[j]->getThickP0().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
if (m_centerLineArray[j]->getThickP1().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (!m_centerLineArray.empty() && m_centerLineArray.back()->getThickP2().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
computeParameterInControlPoint();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::Imp::Imp()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
init();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::Imp::Imp(const std::vector<tthickpoint> &v)</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
buildChunksFromControlPoints(m_centerLineArray, v);
|
|
Toshihiro Shimizu |
890ddd |
roundNegativeThickess(m_centerLineArray);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
init();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::Imp::Imp(const std::vector<tpointd> &v)</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
buildChunksFromControlPoints(m_centerLineArray, v);
|
|
Toshihiro Shimizu |
890ddd |
roundNegativeThickess(m_centerLineArray);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
init();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::swapGeometry(Imp &other) throw()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_flag, other.m_flag);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_isValidLength, other.m_isValidLength);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_isOutlineValid, other.m_isOutlineValid);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_areDisabledComputeOfCaches, other.m_areDisabledComputeOfCaches);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_bBox, other.m_bBox);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_partialLenghtArray, other.m_partialLenghtArray);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_parameterValueAtControlPoint, other.m_parameterValueAtControlPoint);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_centerLineArray, other.m_centerLineArray);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_selfLoop, other.m_selfLoop);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_negativeThicknessPoints, other.m_negativeThicknessPoints);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_averageThickness, other.m_averageThickness);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_maxThickness, other.m_maxThickness);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::computeMaxThickness()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_maxThickness = m_centerLineArray[0]->getThickP0().thick;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_centerLineArray.size(); i++)
|
|
Shinya Kitaoka |
12c444 |
m_maxThickness = std::max({m_maxThickness, m_centerLineArray[i]->getThickP1().thick, m_centerLineArray[i]->getThickP2().thick});
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::computeCacheVector()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_areDisabledComputeOfCaches && !m_isValidLength) {
|
|
Toshihiro Shimizu |
890ddd |
if (getChunkCount() > 0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray.resize(getControlPointCount(), (std::numeric_limits<double>::max)());</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray[0] = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double length = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
int j = 0;
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *tq;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TQuadraticLengthEvaluator lengthEvaluator;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < getChunkCount(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
assert(j <= getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
tq = getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
lengthEvaluator.setQuad(*tq);
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray[j++] = length;
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray[j++] = length + lengthEvaluator.getLengthAt(0.5);
|
|
Toshihiro Shimizu |
890ddd |
length += lengthEvaluator.getLengthAt(1.0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray[j++] = length;
|
|
Toshihiro Shimizu |
890ddd |
assert(j == getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_isValidLength = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::computeParameterInControlPoint()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_areDisabledComputeOfCaches) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!getChunkCount()) {
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.clear();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int controlPointCount = getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.resize(controlPointCount, 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. number of control point is reduced of 1
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
val = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(controlPointCount >= 0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i <= controlPointCount; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
val = i / (double)controlPointCount;
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint[i] = val;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::updateParameterValue(double w,
|
|
Toshihiro Shimizu |
890ddd |
UINT chunk,
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *tq1,
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *tq2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
DoublePair p = retrieveParametersFromChunk(chunk);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT controlPointToErase = 2 * chunk + 1;
|
|
Toshihiro Shimizu |
890ddd |
DoubleIt it = m_parameterValueAtControlPoint.begin();
|
|
Toshihiro Shimizu |
890ddd |
std::advance(it, controlPointToErase);
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double normalizedParam = tq2->getT(tq2->getP1());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<double>::iterator first;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
normalizedParam = proportion(p.second, normalizedParam, 1.0, w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
first = std::upper_bound(
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.end(),
|
|
Toshihiro Shimizu |
890ddd |
normalizedParam);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first != m_parameterValueAtControlPoint.end()) {
|
|
Toshihiro Shimizu |
890ddd |
first = m_parameterValueAtControlPoint.insert(first, normalizedParam);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
first = m_parameterValueAtControlPoint.insert(first, w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
normalizedParam = tq1->getT(tq1->getP1());
|
|
Toshihiro Shimizu |
890ddd |
normalizedParam = proportion(w, normalizedParam, 1.0, p.first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.insert(first, normalizedParam);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
assert( getControlPointCount() <=
|
|
Toshihiro Shimizu |
890ddd |
(int)m_parameterValueAtControlPoint.size() );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getChunkAndTAtLength(double s, int &chunk, double &t) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->retrieveChunkAndItsParamameterAtLength(s, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::Imp::retrieveChunkAndItsParamameterAtLength(double s, int &chunk, double &t)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<double>::iterator first;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
first = std::upper_bound(m_partialLenghtArray.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_partialLenghtArray.end(),
|
|
Toshihiro Shimizu |
890ddd |
s);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first != m_partialLenghtArray.end()) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int controlPointOffset = distance(m_partialLenghtArray.begin(), first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
chunk = retrieveChunkFromControlPointIndex(controlPointOffset);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first != m_partialLenghtArray.begin() && s == *(first - 1)) {
|
|
Toshihiro Shimizu |
890ddd |
controlPointOffset
|
|
Toshihiro Shimizu |
890ddd |
if (controlPointOffset & 1) {
|
|
Toshihiro Shimizu |
890ddd |
const DoublePair &p = retrieveParametersFromChunk(chunk);
|
|
Toshihiro Shimizu |
890ddd |
t = proportion(1.0, getW(controlPointOffset) - p.first, p.second - p.first);
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
t = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
offset = (first == m_partialLenghtArray.begin()) ? s : s - m_partialLenghtArray[chunk * 2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const double tol = TConsts::epsilon * 0.1;
|
|
Toshihiro Shimizu |
890ddd |
int err;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
computeOffset_ op(getChunk(chunk), offset);
|
|
Toshihiro Shimizu |
890ddd |
computeSpeed_ op2(getChunk(chunk));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!findZero_Newton(0.0,
|
|
Toshihiro Shimizu |
890ddd |
1.0,
|
|
Toshihiro Shimizu |
890ddd |
op,
|
|
Toshihiro Shimizu |
890ddd |
op2,
|
|
Toshihiro Shimizu |
890ddd |
tol,
|
|
Toshihiro Shimizu |
890ddd |
tol,
|
|
Toshihiro Shimizu |
890ddd |
100,
|
|
Toshihiro Shimizu |
890ddd |
t,
|
|
Toshihiro Shimizu |
890ddd |
err))
|
|
Toshihiro Shimizu |
890ddd |
t = -1; // if can not find a good value set parameter to error value
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t == -1) {
|
|
Toshihiro Shimizu |
890ddd |
if (s <= m_partialLenghtArray[controlPointOffset])
|
|
Toshihiro Shimizu |
890ddd |
t = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
t = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (s <= 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
chunk = 0;
|
|
Toshihiro Shimizu |
890ddd |
t = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
} else if (s >= m_partialLenghtArray.back()) {
|
|
Toshihiro Shimizu |
890ddd |
chunk = getChunkCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
t = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getChunkAndT(double w, int &chunk, double &t) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->retrieveChunkAndItsParamameter(w, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::Imp::retrieveChunkAndItsParamameter(double w, int &chunk, double &t)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<double>::iterator first;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
first = std::lower_bound(m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_parameterValueAtControlPoint.end(),
|
|
Toshihiro Shimizu |
890ddd |
w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first == m_parameterValueAtControlPoint.end())
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
found = *first;
|
|
Toshihiro Shimizu |
890ddd |
assert(found <= *first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int controlPointOffset = distance(m_parameterValueAtControlPoint.begin(), first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
chunk = retrieveChunkFromControlPointIndex(controlPointOffset);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DoublePair
|
|
Toshihiro Shimizu |
890ddd |
p = retrieveParametersFromChunk(chunk);
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
assert( p.first <= w &&
|
|
Toshihiro Shimizu |
890ddd |
w <= p.second );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
chunk = retrieveChunkFromControlPointIndex( controlPointOffset );
|
|
Toshihiro Shimizu |
890ddd |
p = retrieveParametersFromChunk( chunk );
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w < p.first ||
|
|
Toshihiro Shimizu |
890ddd |
w > p.second) {
|
|
Toshihiro Shimizu |
890ddd |
t = (p.first + p.second) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
t = proportion(1.0, w - p.first, p.second - p.first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
assert( 0.0 <= t && t <= 1.0 );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD TStroke::Imp::computeCenterlineBBox()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT n = m_centerLineArray.size();
|
|
Toshihiro Shimizu |
890ddd |
if (m_centerLineArray.empty())
|
|
Toshihiro Shimizu |
890ddd |
return TRectD();
|
|
Toshihiro Shimizu |
890ddd |
TQuadratic q(m_centerLineArray[0]->getP0(), m_centerLineArray[0]->getP1(), m_centerLineArray[0]->getP2());
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = q.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 1; i < n; i++) {
|
|
Toshihiro Shimizu |
890ddd |
q = TQuadratic(m_centerLineArray[i]->getP0(), m_centerLineArray[i]->getP1(), m_centerLineArray[i]->getP2());
|
|
Toshihiro Shimizu |
890ddd |
bbox += q.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return bbox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD TStroke::Imp::computeSubBBox(double w0, double w1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_centerLineArray.empty())
|
|
Toshihiro Shimizu |
890ddd |
return TRectD();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int n = m_centerLineArray.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bBox;
|
|
Toshihiro Shimizu |
890ddd |
const double eps = 0.000000001;
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 > w1)
|
|
Toshihiro Shimizu |
890ddd |
tswap(w0, w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double nw0 = w0 * n;
|
|
Toshihiro Shimizu |
890ddd |
double nw1 = w1 * n;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int i0 = (int)nw0;
|
|
Toshihiro Shimizu |
890ddd |
int i1 = (int)nw1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t0 = nw0 - (double)i0;
|
|
Toshihiro Shimizu |
890ddd |
double t1 = nw1 - (double)i1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t0 < eps)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
i0
|
|
Toshihiro Shimizu |
890ddd |
t0 = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (t1 > (1 - eps))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
i1++;
|
|
Toshihiro Shimizu |
890ddd |
t1 = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic quadratic1, quadratic2, quadratic3;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (i0 == i1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (t0 < eps && t1 > (1 - eps))
|
|
Toshihiro Shimizu |
890ddd |
return m_centerLineArray[i0]->getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t0 < eps) {
|
|
Toshihiro Shimizu |
890ddd |
m_centerLineArray[i0]->split(t1, quadratic1, quadratic2);
|
|
Toshihiro Shimizu |
890ddd |
return quadratic1.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t1 > (1 - eps)) {
|
|
Toshihiro Shimizu |
890ddd |
m_centerLineArray[i0]->split(t0, quadratic1, quadratic2);
|
|
Toshihiro Shimizu |
890ddd |
return quadratic2.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_centerLineArray[i0]->split(t0, quadratic1, quadratic2);
|
|
Toshihiro Shimizu |
890ddd |
quadratic2.split((t1 - t0) / (1 - t0), quadratic1, quadratic3);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return quadratic1.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// se i due punti di taglio capitano in quadratiche diverse
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = i0 + 1; i < i1; i++)
|
|
Toshihiro Shimizu |
890ddd |
bBox += m_centerLineArray[i]->getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (i0 >= 0 && t0 < (1 - eps)) {
|
|
Toshihiro Shimizu |
890ddd |
m_centerLineArray[i0]->split(t0, quadratic1, quadratic2);
|
|
Toshihiro Shimizu |
890ddd |
bBox += quadratic2.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (i1 < n && t1 > eps) {
|
|
Toshihiro Shimizu |
890ddd |
m_centerLineArray[i1]->split(t1, quadratic1, quadratic2);
|
|
Toshihiro Shimizu |
890ddd |
bBox += quadratic1.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return bBox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::Imp::print(ostream &os)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
#if defined(_DEBUG) || defined(DEBUG)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_isValidLength:" << m_isValidLength << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_isOutlineValid:" << m_isOutlineValid << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_areDisabledComputeOfCaches:" << m_areDisabledComputeOfCaches << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_bBox:" << m_bBox << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_partialLenghtArray";
|
|
Toshihiro Shimizu |
890ddd |
printContainer(os, m_partialLenghtArray);
|
|
Toshihiro Shimizu |
890ddd |
os << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_parameterValueAtControlPoint";
|
|
Toshihiro Shimizu |
890ddd |
printContainer(os, m_parameterValueAtControlPoint);
|
|
Toshihiro Shimizu |
890ddd |
os << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "m_centerLineArray";
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
printContainerOfPointer(os, m_centerLineArray);
|
|
Toshihiro Shimizu |
890ddd |
os << endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
vector<tpixel> m_outlineColorArray;</tpixel>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tpointd> m_texArray;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFilePath m_filePath;
|
|
Toshihiro Shimizu |
890ddd |
TRasterP m_texture;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DEFINE_CLASS_CODE(TStroke, 15)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::TStroke()
|
|
Toshihiro Shimizu |
890ddd |
: TSmartObject(m_classCode)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> p(3);</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
p[0] = TThickPoint(0, 0, 0);
|
|
Toshihiro Shimizu |
890ddd |
p[1] = p[0];
|
|
Toshihiro Shimizu |
890ddd |
p[2] = p[1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
262a92 |
m_imp.reset(new TStroke::Imp(p));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray.push_back ( new TThickQuadratic );
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::TStroke(const vector<tthickpoint> &v)</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
: TSmartObject(m_classCode)
|
|
Shinya Kitaoka |
262a92 |
, m_imp(new TStroke::Imp(v))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::TStroke(const vector<tpointd> &v)</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
: TSmartObject(m_classCode)
|
|
Shinya Kitaoka |
262a92 |
, m_imp(new TStroke::Imp(v))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::~TStroke()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::TStroke(const TStroke &other)
|
|
Toshihiro Shimizu |
890ddd |
: TSmartObject(m_classCode)
|
|
Shinya Kitaoka |
262a92 |
, m_imp(new TStroke::Imp())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_bBox = other.getBBox();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValidLength = other.m_imp->m_isValidLength;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isOutlineValid = other.m_imp->m_isOutlineValid;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_areDisabledComputeOfCaches = other.m_imp->m_areDisabledComputeOfCaches;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_flag = other.m_imp->m_flag;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_outlineOptions = other.m_imp->m_outlineOptions;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray.resize(other.m_imp->m_centerLineArray.size());
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < (int)other.m_imp->m_centerLineArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray[i] = new TThickQuadratic(*other.m_imp->m_centerLineArray[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//copy( other.m_imp->m_centerLineArray.begin(),
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
copy(other.m_imp->m_partialLenghtArray.begin(),
|
|
Toshihiro Shimizu |
890ddd |
other.m_imp->m_partialLenghtArray.end(),
|
|
Toshihiro Shimizu |
890ddd |
back_inserter<doublearray>(m_imp->m_partialLenghtArray));</doublearray>
|
|
Toshihiro Shimizu |
890ddd |
copy(other.m_imp->m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
other.m_imp->m_parameterValueAtControlPoint.end(),
|
|
Toshihiro Shimizu |
890ddd |
back_inserter<doublearray>(m_imp->m_parameterValueAtControlPoint));</doublearray>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_styleId = other.m_imp->m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = 0; //other.m_imp->m_prop ? other.m_imp->m_prop->clone(this) : 0;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_selfLoop = other.m_imp->m_selfLoop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints = other.m_imp->m_negativeThicknessPoints;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke &TStroke::operator=(const TStroke &other)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TStroke temp(other);
|
|
Toshihiro Shimizu |
890ddd |
swap(temp);
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getNearestW(const TPointD &p,
|
|
Toshihiro Shimizu |
890ddd |
double &outW,
|
|
Toshihiro Shimizu |
890ddd |
double &dist2,
|
|
Toshihiro Shimizu |
890ddd |
bool checkBBox) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double outT;
|
|
Toshihiro Shimizu |
890ddd |
int chunkIndex;
|
|
Toshihiro Shimizu |
890ddd |
bool ret = getNearestChunk(p, outT, chunkIndex, dist2, checkBBox);
|
|
Toshihiro Shimizu |
890ddd |
if (ret)
|
|
Toshihiro Shimizu |
890ddd |
outW = getW(chunkIndex, outT);
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getNearestChunk(const TPointD &p,
|
|
Toshihiro Shimizu |
890ddd |
double &outT,
|
|
Toshihiro Shimizu |
890ddd |
int &chunkIndex,
|
|
Toshihiro Shimizu |
890ddd |
double &dist2,
|
|
Toshihiro Shimizu |
890ddd |
bool checkBBox) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dist2 = (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_centerLineArray.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
if (checkBBox && !m_imp->m_centerLineArray[i]->getBBox().enlarge(30).contains(p))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t = (m_imp->m_centerLineArray)[i]->getT(p);
|
|
Toshihiro Shimizu |
890ddd |
double dist = tdistance2((m_imp->m_centerLineArray)[i]->getPoint(t), p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dist < dist2) {
|
|
Toshihiro Shimizu |
890ddd |
dist2 = dist;
|
|
Toshihiro Shimizu |
890ddd |
chunkIndex = i;
|
|
Toshihiro Shimizu |
890ddd |
outT = t;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return dist2 < (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getNearChunks(const TThickPoint &p,
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> &pointsOnStroke,</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
bool checkBBox) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int currIndex = -100;
|
|
Toshihiro Shimizu |
890ddd |
double currDist2 = 100000;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_centerLineArray.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *q = m_imp->m_centerLineArray[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (checkBBox && !q->getBBox().enlarge(30).contains(p))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t = q->getT(p);
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p1 = q->getThickPoint(t);
|
|
Toshihiro Shimizu |
890ddd |
double dist2 = tdistance2(p1, p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dist2 < (p1.thick + p.thick + 5) * (p1.thick + p.thick + 5)) {
|
|
Toshihiro Shimizu |
890ddd |
if (!pointsOnStroke.empty() && areAlmostEqual(p1, pointsOnStroke.back(), 1e-3))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (currIndex == i - 1) {
|
|
Toshihiro Shimizu |
890ddd |
if (dist2 < currDist2)
|
|
Toshihiro Shimizu |
890ddd |
pointsOnStroke.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
currIndex = i;
|
|
Toshihiro Shimizu |
890ddd |
currDist2 = dist2;
|
|
Toshihiro Shimizu |
890ddd |
pointsOnStroke.push_back(p1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return pointsOnStroke.size(); //dist2 < (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::getControlPoints(vector<tthickpoint> &v) const</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(v.empty());
|
|
Toshihiro Shimizu |
890ddd |
v.resize(m_imp->m_centerLineArray.size() * 2 + 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
v[0] = m_imp->m_centerLineArray[0]->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_centerLineArray.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *q = m_imp->m_centerLineArray[i];
|
|
Toshihiro Shimizu |
890ddd |
v[2 * i + 1] = q->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
v[2 * i + 2] = q->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint TStroke::getControlPoint(int n) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (n <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.front()->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (n >= getControlPointCount())
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.back()->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// calcolo l'offset del chunk risolvendo l'equazione
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunkNumber = tceil((n - 1) * 0.5);
|
|
Toshihiro Shimizu |
890ddd |
assert(chunkNumber <= getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int pointOffset = n - chunkNumber * 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkNumber == getChunkCount()) // e' l'ultimo punto della stroke
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunkNumber - 1)->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
switch (pointOffset) {
|
|
Toshihiro Shimizu |
890ddd |
case 0:
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunkNumber)->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunkNumber)->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
case 2:
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunkNumber)->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert("Not yet finished" && false);
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint TStroke::getControlPointAtParameter(double w) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (w <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.front()->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w >= 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.back()->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double>::iterator</double>
|
|
Toshihiro Shimizu |
890ddd |
it_begin = m_imp->m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
first,
|
|
Toshihiro Shimizu |
890ddd |
it_end = m_imp->m_parameterValueAtControlPoint.end();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// find iterator at position greater or equal to w
|
|
Toshihiro Shimizu |
890ddd |
first = std::lower_bound(it_begin, it_end, w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(first != it_end);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//if( areAlmostEqual(*first, w, 0.1) )
|
|
Toshihiro Shimizu |
890ddd |
// return getControlPoint( distance(it_begin, first) );
|
|
Toshihiro Shimizu |
890ddd |
if (first == it_begin)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
else if ((*first - w) <= w - *(first - 1))
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(distance(it_begin, first));
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(distance(it_begin, first - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getControlPointIndexAfterParameter(double w) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const vector<double>::const_iterator</double>
|
|
Toshihiro Shimizu |
890ddd |
begin = m_imp->m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
end = m_imp->m_parameterValueAtControlPoint.end();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double>::const_iterator it =</double>
|
|
Toshihiro Shimizu |
890ddd |
std::upper_bound(begin, end, w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (it == end)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return std::distance(begin, it);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setControlPoint(int n, const TThickPoint &pos)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(n >= 0);
|
|
Toshihiro Shimizu |
890ddd |
assert(n < getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
if (n < 0 || n >= getControlPointCount())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray &chunkArray = m_imp->m_centerLineArray;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (getControlPoint(n).thick <= 0 && pos.thick > 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints--;
|
|
Toshihiro Shimizu |
890ddd |
else if (getControlPoint(n).thick > 0 && pos.thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (n == 0) {
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[0]->setThickP0(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunkNumber = tceil((n - 1) * 0.5);
|
|
Toshihiro Shimizu |
890ddd |
assert(chunkNumber <= getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int pointOffset = n - chunkNumber * 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkNumber == getChunkCount()) // e' l'ultimo punto della stroke
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber - 1]->setThickP2(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0 == pointOffset) {
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber]->setThickP0(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkNumber >= 1) {
|
|
Toshihiro Shimizu |
890ddd |
chunkNumber
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber]->setThickP2(pos);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else if (1 == pointOffset)
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber]->setThickP1(pos);
|
|
Toshihiro Shimizu |
890ddd |
else if (2 == pointOffset) {
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber]->setThickP2(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkNumber < getChunkCount() - 1) {
|
|
Toshihiro Shimizu |
890ddd |
chunkNumber++;
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunkNumber]->setThickP0(pos);
|
|
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 |
void TStroke::reshape(const TThickPoint pos[], int count)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(count >= 3);
|
|
Toshihiro Shimizu |
890ddd |
assert(count & 1);
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray &chunkArray = m_imp->m_centerLineArray;
|
|
Toshihiro Shimizu |
890ddd |
clearPointerContainer(chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < count - 1; i += 2) {
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(new TThickQuadratic(pos[i], pos[i + 1], pos[i + 2]));
|
|
Toshihiro Shimizu |
890ddd |
if (pos[i].thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
if (pos[i + 1].thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (pos[count - 1].thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeParameterInControlPoint();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getApproximateLength(double w0, double w1, double error) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeCacheVector();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert((int)m_imp->m_partialLenghtArray.size() == getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 == w1)
|
|
Toshihiro Shimizu |
890ddd |
return 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
w0 = min(max(0.0, w0), 1.0);
|
|
Toshihiro Shimizu |
890ddd |
w1 = min(max(0.0, w1), 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 > w1)
|
|
Toshihiro Shimizu |
890ddd |
std::swap(w0, w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0.0 == w0) {
|
|
Toshihiro Shimizu |
890ddd |
vector<double>::iterator first;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
first = std::upper_bound(
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_parameterValueAtControlPoint.begin(),
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_parameterValueAtControlPoint.end(),
|
|
Toshihiro Shimizu |
890ddd |
w1 - TConsts::epsilon);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (first != m_imp->m_parameterValueAtControlPoint.end() &&
|
|
Toshihiro Shimizu |
890ddd |
*first < w1 + TConsts::epsilon) {
|
|
Toshihiro Shimizu |
890ddd |
int offset = distance(m_imp->m_parameterValueAtControlPoint.begin(), first);
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_partialLenghtArray[offset];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int firstChunk, secondChunk;
|
|
Toshihiro Shimizu |
890ddd |
double firstT, secondT;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool val1 = m_imp->retrieveChunkAndItsParamameter(w0, firstChunk, firstT);
|
|
Toshihiro Shimizu |
890ddd |
assert(val1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool val2 = m_imp->retrieveChunkAndItsParamameter(w1, secondChunk, secondT);
|
|
Toshihiro Shimizu |
890ddd |
assert(val2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (firstChunk == secondChunk)
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(firstChunk)->getApproximateLength(firstT, secondT, error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double totalLength = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
totalLength += getChunk(firstChunk)->getApproximateLength(firstT, 1, error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = firstChunk + 1; i != secondChunk; i++)
|
|
Toshihiro Shimizu |
890ddd |
totalLength += getChunk(i)->getApproximateLength(0.0, 1.0, error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
totalLength += getChunk(secondChunk)->getApproximateLength(0.0, secondT, error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return totalLength;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getLength(double w0, double w1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (w0 == w1)
|
|
Toshihiro Shimizu |
890ddd |
return 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
w0 = min(max(0.0, w0), 1.0);
|
|
Toshihiro Shimizu |
890ddd |
w1 = min(max(0.0, w1), 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 > w1)
|
|
Toshihiro Shimizu |
890ddd |
std::swap(w0, w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ok = !m_imp->retrieveChunkAndItsParamameter(w1, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
assert(ok);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double s1 = getLength(chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 == 0.0)
|
|
Toshihiro Shimizu |
890ddd |
return s1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ok = !m_imp->retrieveChunkAndItsParamameter(w0, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
assert(ok);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return s1 - getLength(chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getLength(int chunk, double t) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeCacheVector();
|
|
Toshihiro Shimizu |
890ddd |
assert((int)m_imp->m_partialLenghtArray.size() == getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t == 1.0)
|
|
Toshihiro Shimizu |
890ddd |
++chunk, t = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double s = m_imp->m_partialLenghtArray[chunk << 1];
|
|
Toshihiro Shimizu |
890ddd |
if (t > 0.0)
|
|
Toshihiro Shimizu |
890ddd |
s += getChunk(chunk)->getLength(t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return s;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::invalidate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_maxThickness = -1;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isOutlineValid = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValidLength = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_flag = m_imp->m_flag | c_dirty_flag;
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_prop)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop->notifyStrokeChange();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
N.B. Questa funzione e' piu' lenta rispetto alla insertCP
|
|
Toshihiro Shimizu |
890ddd |
perche' ricerca la posizione di s con un algoritmo di bisezione.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::insertControlPointsAtLength(double s)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (0 > s || s > getLength())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->retrieveChunkAndItsParamameterAtLength(s, chunk, t)) {
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(t) || areAlmostEqual(t, 1))
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// calcolo i due "cionchi"
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic
|
|
Toshihiro Shimizu |
890ddd |
*tqfirst = new TThickQuadratic,
|
|
Toshihiro Shimizu |
890ddd |
*tqsecond = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getChunk(chunk)->split(t, *tqfirst, *tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double parameterInStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0 == chunk)
|
|
Toshihiro Shimizu |
890ddd |
parameterInStroke = m_imp->getW(2) * t;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
parameterInStroke = t * m_imp->getW((chunk + 1) * 2) + (1 - t) * m_imp->getW(chunk * 2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->updateParameterValue(parameterInStroke, chunk, tqfirst, tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray::iterator it = m_imp->m_centerLineArray.begin();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
advance(it, chunk);
|
|
Toshihiro Shimizu |
890ddd |
delete *it;
|
|
Toshihiro Shimizu |
890ddd |
it = m_imp->m_centerLineArray.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
it = m_imp->m_centerLineArray.insert(it, tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
it = m_imp->m_centerLineArray.insert(it, tqfirst);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const int
|
|
Toshihiro Shimizu |
890ddd |
size = m_imp->m_parameterValueAtControlPoint.size();
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
prev = m_imp->m_parameterValueAtControlPoint[0];
|
|
Toshihiro Shimizu |
890ddd |
for( int i = 1;
|
|
Toshihiro Shimizu |
890ddd |
i < size;
|
|
Toshihiro Shimizu |
890ddd |
++i )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert( prev <= m_imp->m_parameterValueAtControlPoint[i] );
|
|
Toshihiro Shimizu |
890ddd |
prev = m_imp->m_parameterValueAtControlPoint[i];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::insertControlPoints(double w)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (0.0 > w || w > 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double tOfDivision = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->retrieveChunkAndItsParamameter(w, chunk, tOfDivision))
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(tOfDivision) || areAlmostEqual(tOfDivision, 1))
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= chunk && chunk < getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= tOfDivision && tOfDivision <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// calcolo i due "cionchi"
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic
|
|
Toshihiro Shimizu |
890ddd |
*tqfirst = new TThickQuadratic,
|
|
Toshihiro Shimizu |
890ddd |
*tqsecond = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getChunk(chunk)->split(tOfDivision, *tqfirst, *tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->updateParameterValue(w, chunk, tqfirst, tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray::iterator it = m_imp->m_centerLineArray.begin();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
advance(it, chunk);
|
|
Toshihiro Shimizu |
890ddd |
delete *it;
|
|
Toshihiro Shimizu |
890ddd |
it = m_imp->m_centerLineArray.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
it = m_imp->m_centerLineArray.insert(it, tqsecond);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray.insert(it, tqfirst);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeCacheVector();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < m_imp->m_centerLineArray.size(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_centerLineArray[j]->getThickP0().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_centerLineArray[j]->getThickP1().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_centerLineArray.empty() && m_imp->m_centerLineArray.back()->getThickP2().thick <= 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::reduceControlPoints(double error, vector<int> corners)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double step, quadLen;
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> tempVect, controlPoints;</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
TStroke *tempStroke = 0;
|
|
Toshihiro Shimizu |
890ddd |
double missedLen = 0;
|
|
Toshihiro Shimizu |
890ddd |
UINT cp, nextQuad, quadI, cornI, cpSize, size;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *quad = m_imp->m_centerLineArray.front();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
size = corners.size();
|
|
Toshihiro Shimizu |
890ddd |
assert(size > 1);
|
|
Toshihiro Shimizu |
890ddd |
if (size < 2) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
corners.resize(2);
|
|
Toshihiro Shimizu |
890ddd |
corners[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
corners[1] = m_imp->m_centerLineArray.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (cornI = 0; cornI < size - 1; ++cornI) {
|
|
Toshihiro Shimizu |
890ddd |
tempVect.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
nextQuad = corners[cornI + 1];
|
|
Toshihiro Shimizu |
890ddd |
if (nextQuad > m_imp->m_centerLineArray.size()) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!"bad quadric index");
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (corners[cornI] >= (int)m_imp->m_centerLineArray.size()) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!"bad quadric index");
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (quadI = corners[cornI]; quadI < nextQuad; quadI++) {
|
|
Toshihiro Shimizu |
890ddd |
quad = getChunk(quadI);
|
|
Toshihiro Shimizu |
890ddd |
quadLen = quad->getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
missedLen += quadLen;
|
|
Toshihiro Shimizu |
890ddd |
if (quadLen && (missedLen > 1 || quadI == 0 || quadI == nextQuad - 1)) //err instead of 1?
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
missedLen = 0;
|
|
Toshihiro Shimizu |
890ddd |
step = 1.0 / quadLen;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// simili. e poi difficilmete il punto p1 di una quadratica e' cosi' asimmetrico
|
|
Toshihiro Shimizu |
890ddd |
for (double t = 0; t < 1.0; t += step)
|
|
Toshihiro Shimizu |
890ddd |
tempVect.push_back(quad->getThickPoint(t));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
tempVect.push_back(quad->getThickP2());
|
|
Toshihiro Shimizu |
890ddd |
tempStroke = TStroke::interpolate(tempVect, error, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
cpSize = tempStroke->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
for (cp = 0; cp < cpSize - 1; cp++) {
|
|
Toshihiro Shimizu |
890ddd |
controlPoints.push_back(tempStroke->getControlPoint(cp));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
delete tempStroke;
|
|
Toshihiro Shimizu |
890ddd |
tempStroke = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
controlPoints.push_back(m_imp->m_centerLineArray.back()->getThickP2());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
cpSize = controlPoints.size();
|
|
Toshihiro Shimizu |
890ddd |
for (cp = 1; cp < cpSize; cp++)
|
|
Toshihiro Shimizu |
890ddd |
assert(!(controlPoints[cp - 1] == controlPoints[cp]));
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
reshape(&(controlPoints[0]), controlPoints.size());
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::reduceControlPoints(double error)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<int> corners;</int>
|
|
Toshihiro Shimizu |
890ddd |
corners.push_back(0);
|
|
Toshihiro Shimizu |
890ddd |
detectCorners(this, 10, corners);
|
|
Toshihiro Shimizu |
890ddd |
corners.push_back(getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
reduceControlPoints(error, corners);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getAverageThickness() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_averageThickness;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getMaxThickness()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_maxThickness == -1)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeMaxThickness();
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_maxThickness;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setAverageThickness(double thickness)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_averageThickness = thickness;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::operator==(const TStroke &s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (getChunkCount() != s.getChunkCount())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < getChunkCount(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *chanck = getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *sChanck = s.getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
if (chanck->getThickP0() != sChanck->getThickP0() ||
|
|
Toshihiro Shimizu |
890ddd |
chanck->getThickP1() != sChanck->getThickP1() ||
|
|
Toshihiro Shimizu |
890ddd |
chanck->getThickP2() != sChanck->getThickP2())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getChunkCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getControlPointCount() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *TStroke::getChunk(int index) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->getChunk(index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD TStroke::getBBox(double w0, double w1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (w0 > w1)
|
|
Toshihiro Shimizu |
890ddd |
tswap(w0, w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w0 != 0.0 || w1 != 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->computeSubBBox(w0, w1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_flag & c_dirty_flag)
|
|
Toshihiro Shimizu |
890ddd |
((TStroke *)this)->computeBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_bBox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::computeBBox()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_bBox = TOutlineUtil::computeBBox(*this);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_flag &= ~c_dirty_flag;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD TStroke::getCenterlineBBox() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->computeCenterlineBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::disableComputeOfCaches()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_areDisabledComputeOfCaches = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::enableComputeOfCaches()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_areDisabledComputeOfCaches = false;
|
|
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 |
//DEL if (!rect.contains(p))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
12c444 |
//DEL if (std::min(dist21, dist22, dist23, dist24)>=maxDistance2)
|
|
Toshihiro Shimizu |
890ddd |
//DEL return maxDistance2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//DEL for (UINT i=0; i < m_imp->m_centerLineArray.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//DEL if (distance2 < curMaxDistance2)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//DEL return curMaxDistance2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint TStroke::getThickPointAtLength(double s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!m_imp->m_centerLineArray.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (s <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (s >= getLength())
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(getControlPointCount() - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double tOfDivision;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool error = m_imp->retrieveChunkAndItsParamameterAtLength(s, chunk, tOfDivision);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (error)
|
|
Toshihiro Shimizu |
890ddd |
error = m_imp->retrieveChunkAndItsParamameterAtLength(s, chunk, tOfDivision);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(!error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (error)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunk)->getThickPoint(tOfDivision);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint TStroke::getThickPoint(double w) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!m_imp->m_centerLineArray.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w < 0)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w > 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(getControlPointCount() - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk = 0;
|
|
Toshihiro Shimizu |
890ddd |
double t = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool error = m_imp->retrieveChunkAndItsParamameter(w, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(!error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (error)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return getChunk(chunk)->getThickPoint(t);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getParameterAtLength(double s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (s <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
else if (s >= getLength())
|
|
Toshihiro Shimizu |
890ddd |
return 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->retrieveChunkAndItsParamameterAtLength(s, chunk, t)) {
|
|
Toshihiro Shimizu |
890ddd |
DoublePair p = m_imp->retrieveParametersFromChunk(chunk);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return proportion(p.second, t, 1.0, p.first);
|
|
Toshihiro Shimizu |
890ddd |
} else if (chunk < (int)getChunkCount() && t == -1)
|
|
Toshihiro Shimizu |
890ddd |
return getParameterAtControlPoint(2 * chunk);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getParameterAtControlPoint(int n) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
out = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (0 <= n &&
|
|
Toshihiro Shimizu |
890ddd |
n < getControlPointCount())
|
|
Toshihiro Shimizu |
890ddd |
out = m_imp->getW(n);
|
|
Toshihiro Shimizu |
890ddd |
/* FAB
|
|
Toshihiro Shimizu |
890ddd |
assert( 0.0 <= out &&
|
|
Toshihiro Shimizu |
890ddd |
out <= 1.0 );
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
if (0.0 > out)
|
|
Toshihiro Shimizu |
890ddd |
return 0.0;
|
|
Toshihiro Shimizu |
890ddd |
if (out > 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return 1.0;
|
|
Toshihiro Shimizu |
890ddd |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getW(int chunkIndex, double t) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
DoublePair parRange = m_imp->retrieveParametersFromChunk(chunkIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double w = proportion(parRange.second, t, 1.0, parRange.first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= w && w <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return w;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getW(const TPointD &p) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int chunkIndex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double
|
|
Toshihiro Shimizu |
890ddd |
tOfchunk,
|
|
Toshihiro Shimizu |
890ddd |
distance2 = (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getNearestChunk(p, tOfchunk, chunkIndex, distance2, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= chunkIndex && chunkIndex <= getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DoublePair parRange = m_imp->retrieveParametersFromChunk(chunkIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t = proportion(parRange.second, tOfchunk, 1.0, parRange.first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= t && t <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return t;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getSpeedTwoValues(double w, TPointD &speed0, TPointD &speed1) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool ret = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(!m_imp->m_centerLineArray.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w < 0) {
|
|
Toshihiro Shimizu |
890ddd |
speed0 = m_imp->m_centerLineArray.front()->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w > 1.0) {
|
|
Toshihiro Shimizu |
890ddd |
speed0 = m_imp->m_centerLineArray.back()->getSpeed(1.0);
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool error = m_imp->retrieveChunkAndItsParamameter(w, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(!error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (error) {
|
|
Toshihiro Shimizu |
890ddd |
speed0 = m_imp->m_centerLineArray.front()->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
speed1 = -speed0;
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
speed0 = getChunk(chunk)->getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
speed1 = -speed0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(t, 0.0, 1e-9) && chunk > 0 && (speed1 = -getChunk(chunk - 1)->getSpeed(1.0)) != -speed0)
|
|
Toshihiro Shimizu |
890ddd |
ret = true;
|
|
Toshihiro Shimizu |
890ddd |
else if (areAlmostEqual(t, 1.0, 1e-9) && chunk < getChunkCount() - 1 && (speed1 = -getChunk(chunk + 1)->getSpeed(0.0)) != -speed0) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD aux = -speed0;
|
|
Toshihiro Shimizu |
890ddd |
speed0 = -speed1;
|
|
Toshihiro Shimizu |
890ddd |
speed1 = aux;
|
|
Toshihiro Shimizu |
890ddd |
ret = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (speed0 == TPointD())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
while (speed0 == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
speed0 = getChunk(chunk
|
|
Toshihiro Shimizu |
890ddd |
if (chunk <= 0)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
chunk = 0;
|
|
Toshihiro Shimizu |
890ddd |
while (speed0 == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
speed0 = getChunk(chunk++)->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
if (chunk >= getChunkCount() - 1)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (speed0 == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
if (getChunkCount() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q = getChunk(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (q->getP0() == q->getP1() &&
|
|
Toshihiro Shimizu |
890ddd |
q->getP1() != q->getP2())
|
|
Toshihiro Shimizu |
890ddd |
speed0 = TSegment(q->getP1(), q->getP2()).getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
else if (q->getP1() == q->getP2() &&
|
|
Toshihiro Shimizu |
890ddd |
q->getP0() != q->getP1())
|
|
Toshihiro Shimizu |
890ddd |
speed0 = TSegment(q->getP0(), q->getP1()).getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
assert(speed0 != TPointD());
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
assert(speed0 != TPointD());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD TStroke::getSpeed(double w, bool outSpeed) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!m_imp->m_centerLineArray.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w < 0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.front()->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (w > 1.0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.back()->getSpeed(1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool error = m_imp->retrieveChunkAndItsParamameter(w, chunk, t);
|
|
Toshihiro Shimizu |
890ddd |
if (t == 1 && outSpeed && chunk < getChunkCount() - 1) {
|
|
Toshihiro Shimizu |
890ddd |
chunk++;
|
|
Toshihiro Shimizu |
890ddd |
t = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
assert(!error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (error)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_centerLineArray.front()->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD speed = getChunk(chunk)->getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (speed == TPointD())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
while (speed == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
speed = getChunk(chunk
|
|
Toshihiro Shimizu |
890ddd |
if (chunk <= 0)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
chunk = 0;
|
|
Toshihiro Shimizu |
890ddd |
while (speed == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
speed = getChunk(chunk++)->getSpeed(0.0);
|
|
Toshihiro Shimizu |
890ddd |
if (chunk >= getChunkCount() - 1)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (speed == TPointD()) {
|
|
Toshihiro Shimizu |
890ddd |
if (getChunkCount() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q = getChunk(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (q->getP0() == q->getP1() &&
|
|
Toshihiro Shimizu |
890ddd |
q->getP1() != q->getP2())
|
|
Toshihiro Shimizu |
890ddd |
return TSegment(q->getP1(), q->getP2()).getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
else if (q->getP1() == q->getP2() &&
|
|
Toshihiro Shimizu |
890ddd |
q->getP0() != q->getP1())
|
|
Toshihiro Shimizu |
890ddd |
return TSegment(q->getP0(), q->getP1()).getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
assert(speed != TPointD());
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
assert(speed != TPointD());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return speed;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD TStroke::getSpeedAtLength(double s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double t = getParameterAtLength(s);
|
|
Toshihiro Shimizu |
890ddd |
return getSpeed(t);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double TStroke::getLengthAtControlPoint(int n) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->computeCacheVector();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (n >= getControlPointCount())
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_partialLenghtArray.back();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (n <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_partialLenghtArray.front();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_partialLenghtArray[n];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::split(double w, TStroke &f, TStroke &s) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int chunk;
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
f.m_imp->m_maxThickness = -1;
|
|
Toshihiro Shimizu |
890ddd |
s.m_imp->m_maxThickness = -1;
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->retrieveChunkAndItsParamameter(w, chunk, t)) {
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= chunk && chunk < getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= w && w <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= t && t <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray &chunkArray = m_imp->m_centerLineArray;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic
|
|
Toshihiro Shimizu |
890ddd |
*tq1 = new TThickQuadratic,
|
|
Toshihiro Shimizu |
890ddd |
*tq2 = new TThickQuadratic;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
chunkArray[chunk]->split(t, *tq1, *tq2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QuadStrokeChunkArray vTQ;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// copy all chunk of stroke in a vTQ
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < chunk; ++i)
|
|
Toshihiro Shimizu |
890ddd |
vTQ.push_back(chunkArray[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// not insert null length chunk (unless vTQ is empty....)
|
|
Toshihiro Shimizu |
890ddd |
if (tq1->getLength() != 0.0 || w == 0.0 || vTQ.empty())
|
|
Toshihiro Shimizu |
890ddd |
vTQ.push_back(tq1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *ts1 = TStroke::create(vTQ);
|
|
Toshihiro Shimizu |
890ddd |
if (!ts1)
|
|
Toshihiro Shimizu |
890ddd |
ts1 = new TStroke;
|
|
Toshihiro Shimizu |
890ddd |
ts1->swapGeometry(f);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vTQ.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tq2->getLength() != 0.0 || w == 1.0 || getChunkCount() == 0)
|
|
Toshihiro Shimizu |
890ddd |
vTQ.push_back(tq2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = chunk + 1; i < getChunkCount(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
vTQ.push_back(chunkArray[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *ts2 = TStroke::create(vTQ);
|
|
Toshihiro Shimizu |
890ddd |
if (!ts2)
|
|
Toshihiro Shimizu |
890ddd |
ts2 = new TStroke;
|
|
Toshihiro Shimizu |
890ddd |
ts2->swapGeometry(s);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Copy style infos
|
|
Toshihiro Shimizu |
890ddd |
f.setStyle(getStyle());
|
|
Toshihiro Shimizu |
890ddd |
s.setStyle(getStyle());
|
|
Toshihiro Shimizu |
890ddd |
f.outlineOptions() = s.outlineOptions() = outlineOptions();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete ts2;
|
|
Toshihiro Shimizu |
890ddd |
delete ts1;
|
|
Toshihiro Shimizu |
890ddd |
// delete temporary quadratic
|
|
Toshihiro Shimizu |
890ddd |
delete tq1;
|
|
Toshihiro Shimizu |
890ddd |
delete tq2;
|
|
Toshihiro Shimizu |
890ddd |
if (f.getControlPointCount() == 3 && f.getControlPoint(0) != f.getControlPoint(2))
|
|
Toshihiro Shimizu |
890ddd |
f.insertControlPoints(0.5);
|
|
Toshihiro Shimizu |
890ddd |
if (s.getControlPointCount() == 3 && s.getControlPoint(0) != s.getControlPoint(2))
|
|
Toshihiro Shimizu |
890ddd |
s.insertControlPoints(0.5);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::print(ostream &os) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//m_imp->print(os);
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << "Punti di controllo\n";
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < getChunkCount(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
os << "quad #" << i << ":" << endl;
|
|
Toshihiro Shimizu |
890ddd |
q = getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << " P0:" << q->getThickP0().x << ", " << q->getThickP0().y << ", " << q->getThickP0().thick << endl;
|
|
Toshihiro Shimizu |
890ddd |
os << " P1:" << q->getThickP1().x << ", " << q->getThickP1().y << ", " << q->getThickP1().thick << endl;
|
|
Toshihiro Shimizu |
890ddd |
assert(i == getChunkCount() - 1 || (getChunk(i)->getThickP2() == getChunk(i + 1)->getThickP0()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
q = getChunk(getChunkCount() - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
os << " P2:" << q->getThickP2().x << ", " << q->getThickP2().y << ", " << q->getThickP2().thick << endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::transform(const TAffine &aff, bool doChangeThickness)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_imp->m_centerLineArray.size(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic &ref = *m_imp->m_centerLineArray[i];
|
|
Toshihiro Shimizu |
890ddd |
ref = transformQuad(aff, ref, doChangeThickness);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (doChangeThickness) {
|
|
Toshihiro Shimizu |
890ddd |
double det = aff.det();
|
|
Toshihiro Shimizu |
890ddd |
if (det == 0)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_negativeThicknessPoints = getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_maxThickness != -1)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_maxThickness *= sqrt(fabs(det));
|
|
Toshihiro Shimizu |
890ddd |
//else if(det<0)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::draw(const TVectorRenderData &rd) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if(! m_imp->m_styleId)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TColorStyle * style = rd.m_palette->getStyle(m_imp->m_styleId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if( !style->isStrokeStyle() || style->isEnabled() == false )
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = style->makeStrokeProp(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop->draw(rd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStrokeProp *TStroke::getProp() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
#if DISEGNO_OUTLINE == 0
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_styleId)
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TColorStyle * style = palette->getStyle(m_imp->m_styleId);
|
|
Toshihiro Shimizu |
890ddd |
if( !style->isStrokeStyle() || style->isEnabled() == false )
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = style->makeStrokeProp(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setProp(TStrokeProp *prop)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(prop);
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = prop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getStyle() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setStyle(int styleId)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_styleId = styleId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (!colorStyle || (colorStyle && colorStyle->isStrokeStyle()) )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_colorStyle = colorStyle;
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_prop;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke &TStroke::changeDirection()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT chunkCount = getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
UINT to = tfloor(chunkCount * 0.5);
|
|
Toshihiro Shimizu |
890ddd |
UINT i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (chunkCount & 1)
|
|
Toshihiro Shimizu |
890ddd |
changeTQDirection(m_imp->m_centerLineArray[to]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < to; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
changeTQDirection(m_imp->m_centerLineArray[i]);
|
|
Toshihiro Shimizu |
890ddd |
changeTQDirection(m_imp->m_centerLineArray[chunkCount - i]);
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *q1 = m_imp->m_centerLineArray[i];
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray[i] = m_imp->m_centerLineArray[chunkCount - i];
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_centerLineArray[chunkCount - i] = q1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setFlag(TStrokeFlag flag, bool status)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (status)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_flag |= flag;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_flag &= ~flag;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::getFlag(TStrokeFlag flag) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return (m_imp->m_flag & flag) != 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::swap(TStroke &ref)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_imp, ref.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_prop)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_prop->setStroke(this);
|
|
Toshihiro Shimizu |
890ddd |
if (ref.m_imp->m_prop)
|
|
Toshihiro Shimizu |
890ddd |
ref.m_imp->m_prop->setStroke(&ref);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//The id is retained. This is coherent as the stroke id is supposedly
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::swap(m_imp->m_id, ref.m_imp->m_id);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::swapGeometry(TStroke &ref)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->swapGeometry(*ref.m_imp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int TStroke::getId() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_id;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setId(int id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_id = id;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//magari poi la sposto in un altro file
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint TStroke::getCentroid() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double totalLen = getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (totalLen == 0)
|
|
Toshihiro Shimizu |
890ddd |
return getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double step = totalLen * 0.1;
|
|
Toshihiro Shimizu |
890ddd |
double len = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (step > 10.0)
|
|
Toshihiro Shimizu |
890ddd |
step = 10.0;
|
|
Toshihiro Shimizu |
890ddd |
int count = 0;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint point;
|
|
Toshihiro Shimizu |
890ddd |
for (; len <= totalLen; len += step) {
|
|
Toshihiro Shimizu |
890ddd |
count++;
|
|
Toshihiro Shimizu |
890ddd |
point += getThickPointAtLength(len);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return point * (1.0 / (double)count);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TStroke::setSelfLoop(bool loop)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (loop) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const int
|
|
Toshihiro Shimizu |
890ddd |
cpCount = this->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint
|
|
Toshihiro Shimizu |
890ddd |
p,
|
|
Toshihiro Shimizu |
890ddd |
p0 = this->getControlPoint(0),
|
|
Toshihiro Shimizu |
890ddd |
pn = this->getControlPoint(cpCount - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(areAlmostEqual(p0,
|
|
Toshihiro Shimizu |
890ddd |
pn,
|
|
Toshihiro Shimizu |
890ddd |
2));
|
|
Toshihiro Shimizu |
890ddd |
p = (p0 + pn) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
this->setControlPoint(0,
|
|
Toshihiro Shimizu |
890ddd |
p);
|
|
Toshihiro Shimizu |
890ddd |
this->setControlPoint(cpCount - 1,
|
|
Toshihiro Shimizu |
890ddd |
p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_selfLoop = loop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::isSelfLoop() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_selfLoop;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TStroke::isCenterLine() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(m_imp->m_negativeThicknessPoints <= getControlPointCount());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_negativeThicknessPoints == getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::OutlineOptions &TStroke::outlineOptions()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_outlineOptions;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TStroke::OutlineOptions &TStroke::outlineOptions() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_outlineOptions;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// End Of File
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *joinStrokes(const TStroke *s0, const TStroke *s1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TStroke *newStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (s0 == s1) {
|
|
Toshihiro Shimizu |
890ddd |
newStroke = new TStroke(*s0);
|
|
Toshihiro Shimizu |
890ddd |
newStroke->setSelfLoop();
|
|
Toshihiro Shimizu |
890ddd |
return newStroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> v;</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < s0->getControlPointCount(); i++)
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(s0->getControlPoint(i));
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(v.back(), s1->getControlPoint(0), 1e-3))
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < s1->getControlPointCount(); i++)
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(s1->getControlPoint(i));
|
|
Toshihiro Shimizu |
890ddd |
else if (areAlmostEqual(v.back(), s1->getControlPoint(s1->getControlPointCount() - 1), 1e-3))
|
|
Toshihiro Shimizu |
890ddd |
for (i = s1->getControlPointCount() - 2; i >= 0; i
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(s1->getControlPoint(i));
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
assert(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
newStroke = new TStroke(v);
|
|
Toshihiro Shimizu |
890ddd |
newStroke->setStyle(s0->getStyle());
|
|
Toshihiro Shimizu |
890ddd |
newStroke->outlineOptions() = s0->outlineOptions();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return newStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
int cpCount1 = stroke1->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
int cpCount2 = stroke2->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int qCount1 = stroke1->getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic* q1=stroke1->getChunk(qCount1-1 );
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic* q2=stroke2->getChunk(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint extreme1 = q1->getThickP2() ;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint extreme2 = q2->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> points;</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
points.reserve(cpCount1+cpCount2-1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int i = 0;
|
|
Toshihiro Shimizu |
890ddd |
for(; i!=cpCount1-1; i++)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back( stroke1->getControlPoint(i));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if(extreme1==extreme2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(extreme1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double len1=q1->getLength();
|
|
Toshihiro Shimizu |
890ddd |
assert(len1>=0);
|
|
Toshihiro Shimizu |
890ddd |
if(len1<=0)
|
|
Toshihiro Shimizu |
890ddd |
len1=0;
|
|
Toshihiro Shimizu |
890ddd |
double w1= exp(-len1*0.01);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double len2=q2->getLength();
|
|
Toshihiro Shimizu |
890ddd |
assert(len2>=0);
|
|
Toshihiro Shimizu |
890ddd |
if(len2<=0)
|
|
Toshihiro Shimizu |
890ddd |
len2=0;
|
|
Toshihiro Shimizu |
890ddd |
double w2= exp(-len2*0.01);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint m1=q1->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint m2=q2->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p1= extreme1*(1-w1)+m1*w1;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p2= extreme2*(1-w2)+m2*w2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint middleP= (p1 + p2)*0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double angle=fabs(cross(normalize(m1-middleP),normalize(m2-middleP)));
|
|
Toshihiro Shimizu |
890ddd |
if( angle< 0.05)
|
|
Toshihiro Shimizu |
890ddd |
middleP=(m1+m2)*0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(middleP);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for(i = 1; i!=cpCount2; i++)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back( stroke2->getControlPoint(i));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
newStroke = new TStroke(points);
|
|
Toshihiro Shimizu |
890ddd |
newStroke->setStyle(stroke1->getStyle());
|
|
Toshihiro Shimizu |
890ddd |
return newStroke;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int local_intersect(const TStroke &stroke,
|
|
Toshihiro Shimizu |
890ddd |
const TSegment &segment,
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> &intersections,</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
bool strokeIsFirst)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *chunk;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < stroke.getChunkCount(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> localIntersections;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
chunk = stroke.getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (intersect(*chunk, segment, localIntersections)) {
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < localIntersections.size(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
double strokePar = localIntersections[j].first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
strokePar = stroke.getW(chunk->getPoint(strokePar));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// check for multiple solution
|
|
Toshihiro Shimizu |
890ddd |
DoublePair
|
|
Toshihiro Shimizu |
890ddd |
sol(strokeIsFirst ? strokePar : localIntersections[j].second,
|
|
Toshihiro Shimizu |
890ddd |
strokeIsFirst ? localIntersections[j].second : strokePar);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair>::iterator it_end = intersections.end();</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (it_end == std::find(intersections.begin(), it_end, sol))
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(sol);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return intersections.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool almostOverlaps(const TRectD &r0, const TRectD &r1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (r0.overlaps(r1))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if ((r0.x1 < r1.x0) && (areAlmostEqual(r0.x1, r1.x0, 1e-5)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
else if ((r1.x1 < r0.x0) && (areAlmostEqual(r1.x1, r0.x0, 1e-5)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
if ((r0.y1 < r1.y0) && (areAlmostEqual(r0.y1, r1.y0, 1e-5)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
else if ((r1.y1 < r0.y0) && (areAlmostEqual(r1.y1, r0.y0, 1e-5)))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool greaterThanOneAndLesserThanZero(double val)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (val > 1.0 || val < 0.0)
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int intersect(const TStroke *s1,
|
|
Toshihiro Shimizu |
890ddd |
const TStroke *s2,
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> &intersections,</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
bool checkBBox)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
UINT k = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
intersections.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (checkBBox && !s1->getBBox().overlaps(s2->getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < s1->getChunkCount(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
const TQuadratic *q1 = s1->getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
if (q1->getP0() == q1->getP2() && q1->getP1() == q1->getP2())
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
int j = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (s1 == s2) //this 'if': if after i-th stroke there are degenere strokes,
|
|
Toshihiro Shimizu |
890ddd |
//I do not consider them; so, instead of starting from j = i+2
|
|
Toshihiro Shimizu |
890ddd |
//I start from j = i+2+numDegeneres
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
j = i + 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (j <= s2->getChunkCount()) {
|
|
Toshihiro Shimizu |
890ddd |
const TQuadratic *qAux = s2->getChunk(j - 1);
|
|
Toshihiro Shimizu |
890ddd |
if (qAux->getP0() != qAux->getP2() || qAux->getP1() != qAux->getP2())
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
j++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (; j < s2->getChunkCount(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
const TQuadratic *q2 = s2->getChunk(j);
|
|
Toshihiro Shimizu |
890ddd |
if (q2->getP0() == q2->getP2() && q2->getP1() == q2->getP2())
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!almostOverlaps(q1->getBBox(), q2->getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
#ifdef CHECK_DEGLI_ESTREMI
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair> quadIntersections1;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
if (i == 0 || i == s1->getChunkCount() - 1) && (j==0 || j==s2->getChunkCount()-1))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp1 = (i == 0 ? q1->getP0() : q1->getP2());
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp2 = (j == 0 ? q2->getP0() : q2->getP2());
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(pp1, pp2)) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(DoublePair(i == 0 ? 0.0 : 1.0, j == 0 ? 0.0 : 1.0));
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (s1->getChunkCount() == 1 && s2->getChunkCount() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp1 = q1->getP2();
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp2 = q2->getP2();
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(pp1, pp2)) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(DoublePair(1.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (s1->getChunkCount() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp1 = q1->getP2();
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp2 = (j == 0 ? q2->getP0() : q2->getP2());
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(pp1, pp2)) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(DoublePair(1.0, j == 0 ? 0.0 : 1.0));
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (s2->getChunkCount() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp1 = (i == 0 ? q1->getP0() : q1->getP2());
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp2 = q2->getP2();
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(pp1, pp2)) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(DoublePair(i == 0 ? 0.0 : 1.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//if (j<s2->getChunkCount()-1)</s2->
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (*q1 == *q2 ||
|
|
Toshihiro Shimizu |
890ddd |
(q1->getP0() == q2->getP2() && q1->getP1() == q2->getP1() && q1->getP2() == q2->getP0())) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<doublepair> quadIntersections;</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
if (intersect(*q1, *q2, quadIntersections))
|
|
Toshihiro Shimizu |
890ddd |
for (int h = 0; h < (int)quadIntersections.size(); h++) {
|
|
Toshihiro Shimizu |
890ddd |
DoublePair res(getWfromChunkAndT(s1, i, quadIntersections[h].first),
|
|
Toshihiro Shimizu |
890ddd |
getWfromChunkAndT(s2, j, quadIntersections[h].second));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(quadIntersections[h].first, 0) || areAlmostEqual(quadIntersections[h].first, 1) ||
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(quadIntersections[h].second, 0) || areAlmostEqual(quadIntersections[h].second, 1)) {
|
|
Toshihiro Shimizu |
890ddd |
int q = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (q = 0; q < (int)intersections.size(); q++)
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(intersections[q].first, res.first, 1e-8) &&
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(intersections[q].second, res.second, 1e-8))
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
if (q < (int)intersections.size())
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(res);
|
|
Toshihiro Shimizu |
890ddd |
//if (k==0 || intersections[k].first!=intersections[k-1].first || intersections[k].second!=intersections[k-1].second)
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (s1 == s2 && (s1->isSelfLoop() || s1->getPoint(0.0) == s1->getPoint(1.0))) {
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < (int)intersections.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!(areAlmostEqual(intersections[i].first, 1.0, 1e-1) && areAlmostEqual(intersections[i].second, 0.0, 1e-1)));
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(intersections[i].first, 0.0, 1e-1) && areAlmostEqual(intersections[i].second, 1.0, 1e-1))
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (i == (int)intersections.size()) {
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(DoublePair(0.0, 1.0));
|
|
Toshihiro Shimizu |
890ddd |
k++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return k;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int intersect(const TSegment &segment,
|
|
Toshihiro Shimizu |
890ddd |
const TStroke &stroke,
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> &intersections)</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return local_intersect(stroke, segment, intersections, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int intersect(const TStroke &stroke,
|
|
Toshihiro Shimizu |
890ddd |
const TSegment &segment,
|
|
Toshihiro Shimizu |
890ddd |
std::vector<doublepair> &intersections)</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return local_intersect(stroke, segment, intersections, true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int intersect(const TStroke &stroke,
|
|
Toshihiro Shimizu |
890ddd |
const TPointD ¢er,
|
|
Toshihiro Shimizu |
890ddd |
double radius,
|
|
Toshihiro Shimizu |
890ddd |
vector<double> &intersections)</double>
|
|
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 |
const int a = 2;
|
|
Toshihiro Shimizu |
890ddd |
const int b = 1;
|
|
Toshihiro Shimizu |
890ddd |
const int c = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tpointd> bez(3);</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
vector<tpointd> pol(3);</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
vector<double> coeff(5);</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int chunk = 0; chunk < stroke.getChunkCount(); ++chunk) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *tq = stroke.getChunk(chunk);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bez[0] = tq->getP0();
|
|
Toshihiro Shimizu |
890ddd |
bez[1] = tq->getP1();
|
|
Toshihiro Shimizu |
890ddd |
bez[2] = tq->getP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bezier2poly(bez, pol);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pol[c] -= center;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
coeff[4] = sq(pol[a].x) + sq(pol[a].y);
|
|
Toshihiro Shimizu |
890ddd |
coeff[3] = 2.0 * (pol[a].x * pol[b].x + pol[a].y * pol[b].y);
|
|
Toshihiro Shimizu |
890ddd |
coeff[2] = 2.0 * (pol[a].x * pol[c].x + pol[a].y * pol[c].y) + sq(pol[b].x) + sq(pol[b].y);
|
|
Toshihiro Shimizu |
890ddd |
coeff[1] = 2.0 * (pol[b].x * pol[c].x + pol[b].y * pol[c].y);
|
|
Toshihiro Shimizu |
890ddd |
coeff[0] = sq(pol[c].x) + sq(pol[c].y) - sq(radius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double> sol;</double>
|
|
Toshihiro Shimizu |
890ddd |
rootFinding(coeff, sol);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
sol.erase(remove_if(sol.begin(),
|
|
Toshihiro Shimizu |
890ddd |
sol.end(),
|
|
Toshihiro Shimizu |
890ddd |
greaterThanOneAndLesserThanZero),
|
|
Toshihiro Shimizu |
890ddd |
sol.end());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 0; j < sol.size(); ++j)
|
|
Toshihiro Shimizu |
890ddd |
intersections.push_back(getWfromChunkAndT(&stroke, chunk, sol[j]));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(DEBUG) || defined(_DEBUG)
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
cout<<"interesections:";
|
|
Toshihiro Shimizu |
890ddd |
copy( intersections.begin(), intersections.end(), ostream_iterator<double>( cout, " " ) );</double>
|
|
Toshihiro Shimizu |
890ddd |
cout<
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double> test;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
adjacent_difference(intersections.begin(), intersections.end(), back_inserter(test));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (!test.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
assert(test.back() >= 0);
|
|
Toshihiro Shimizu |
890ddd |
test.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return intersections.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void splitStroke(const TStroke &tq,
|
|
Toshihiro Shimizu |
890ddd |
const vector<double> &pars,</double>
|
|
Toshihiro Shimizu |
890ddd |
std::vector<tstroke *=""> &v)</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (pars.empty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT
|
|
Toshihiro Shimizu |
890ddd |
i,
|
|
Toshihiro Shimizu |
890ddd |
vSize = pars.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<double> length(vSize);</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < vSize; ++i)
|
|
Toshihiro Shimizu |
890ddd |
length[i] = tq.getLength(pars[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::adjacent_difference(length.begin(), length.end(), length.begin());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *q1, q2, q3;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
q1 = new TStroke();
|
|
Toshihiro Shimizu |
890ddd |
tq.split(pars[0], *q1, q2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(areAlmostEqual(q1->getLength(), length[0], 1e-4));
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(q1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < vSize; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
q1 = new TStroke();
|
|
Toshihiro Shimizu |
890ddd |
double par = q2.getParameterAtLength(length[i]);
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= par && par <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
q2.split(par, *q1, q3);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(areAlmostEqual(q1->getLength(), length[i], 1e-4));
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(q1);
|
|
Toshihiro Shimizu |
890ddd |
q2 = q3;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
v.push_back(new TStroke(q2));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void detectCorners(const TStroke *stroke, double minDegree, std::vector<int> &corners)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
ee259f |
const double minSin = fabs(sin(minDegree * M_PI_180));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *quad1 = 0;
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *quad2 = 0;
|
|
Toshihiro Shimizu |
890ddd |
UINT quadCount1 = stroke->getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
TPointD speed1, speed2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD tan1, tan2;
|
|
Toshihiro Shimizu |
890ddd |
quad1 = stroke->getChunk(0);
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j = 1; j < quadCount1; j++) {
|
|
Toshihiro Shimizu |
890ddd |
quad2 = stroke->getChunk(j);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
speed1 = quad1->getSpeed(1);
|
|
Toshihiro Shimizu |
890ddd |
speed2 = quad2->getSpeed(0);
|
|
Toshihiro Shimizu |
890ddd |
if (!(speed1 == TPointD() || speed2 == TPointD())) {
|
|
Toshihiro Shimizu |
890ddd |
tan1 = normalize(speed1);
|
|
Toshihiro Shimizu |
890ddd |
tan2 = normalize(speed2);
|
|
Toshihiro Shimizu |
890ddd |
if (tan1 * tan2 < 0 || fabs(cross(tan1, tan2)) >= minSin)
|
|
Toshihiro Shimizu |
890ddd |
corners.push_back(j);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
quad1 = quad2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool removeNullQuadratic(TStroke *stroke, bool checkThickness = true)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> points;</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
UINT i, qCount = stroke->getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *q;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p1, p2, p3;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//se i punti coincidono e' una stroke puntiforme ed e' ammessa
|
|
Toshihiro Shimizu |
890ddd |
if (qCount == 1)
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool check = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i != qCount; i++) {
|
|
Toshihiro Shimizu |
890ddd |
q = stroke->getChunk(i);
|
|
Toshihiro Shimizu |
890ddd |
p1 = q->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
p2 = q->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
p3 = q->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (areAlmostEqual(p1.x, p2.x) && areAlmostEqual(p2.x, p3.x) &&
|
|
Toshihiro Shimizu |
890ddd |
areAlmostEqual(p1.y, p2.y) && areAlmostEqual(p2.y, p3.y) &&
|
|
Toshihiro Shimizu |
890ddd |
(!checkThickness ||
|
|
Toshihiro Shimizu |
890ddd |
(areAlmostEqual(p1.thick, p2.thick) && areAlmostEqual(p2.thick, p3.thick)))) {
|
|
Toshihiro Shimizu |
890ddd |
//assert(!"null quadratic");
|
|
Toshihiro Shimizu |
890ddd |
check = true;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(p1);
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(p2);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (check) {
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(p3);
|
|
Toshihiro Shimizu |
890ddd |
stroke->reshape(&(points[0]), points.size());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return check;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Converte un TThickPoint p0 in un T3DPoint
|
|
Toshihiro Shimizu |
890ddd |
inline T3DPointD thickPntTo3DPnt(const TThickPoint &p0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return T3DPointD(p0.x, p0.y, p0.thick);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Converte un vettore di TThickPoint from in un vettore di T3DPointD to
|
|
Toshihiro Shimizu |
890ddd |
void convert(const vector<tthickpoint> &from, vector<t3dpointd> &to)</t3dpointd></tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
to.resize(from.size());
|
|
Toshihiro Shimizu |
890ddd |
transform(from.begin(), from.end(), to.begin(), thickPntTo3DPnt);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef vector<tthickcubic *=""> TThickCubicArray;</tthickcubic>
|
|
Toshihiro Shimizu |
890ddd |
typedef vector<tthickquadratic *=""> QuadStrokeChunkArray;</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Restituisce un puntatore ad un array di double che contiene la distanza tra
|
|
Toshihiro Shimizu |
890ddd |
il primo punto e i successivi diviso la distanza tra il primo punto e l'ultimo
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
double *chordLengthParameterize3D(const T3DPointD *pointsArrayBegin,
|
|
Toshihiro Shimizu |
890ddd |
int size)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double *u = new double[size];
|
|
Toshihiro Shimizu |
890ddd |
u[0] = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < size; i++)
|
|
Toshihiro Shimizu |
890ddd |
u[i] = u[i - 1] + tdistance(*(pointsArrayBegin + i), *(pointsArrayBegin + i - 1));
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < size; i++) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!isAlmostZero(u[size - 1]));
|
|
Toshihiro Shimizu |
890ddd |
u[i] = u[i] / u[size - 1];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return u;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Returns a \a measure of the maximal discrepancy of the points specified
|
|
Toshihiro Shimizu |
890ddd |
by pointsArray from the corresponding cubic(u[]) points.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
double computeMaxError3D(const TThickCubic &cubic,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD *pointsArrayBegin,
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
double *u,
|
|
Toshihiro Shimizu |
890ddd |
int &splitPoint)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double err, maxErr = 0;
|
|
Toshihiro Shimizu |
890ddd |
splitPoint = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 1; i < size - 1; i++) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef USE_NEW_3D_ERROR_COMPUTE
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//same relative position from centers. It's easily verifiable that
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TThickPoint &A(cubic.getThickPoint(u[i]));
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &B(pointsArrayBegin[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
err = sqrt(sq(B.x - A.x) + sq(B.y - A.y)) + fabs(B.z - A.thick);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD delta = thickPntTo3DPnt(cubic.getThickPoint(u[i])) - *(pointsArrayBegin + i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double thick = cubic.getThickPoint(u[i]).thick;
|
|
Toshihiro Shimizu |
890ddd |
if (thick <= 2.0)
|
|
Toshihiro Shimizu |
890ddd |
thick = 2.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
err = norm2(TPointD(delta.x, delta.y)) / thick;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (fabs(delta.z) > 2.0)
|
|
Toshihiro Shimizu |
890ddd |
err = err + fabs(delta.z);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (err >= maxErr) {
|
|
Toshihiro Shimizu |
890ddd |
maxErr = err;
|
|
Toshihiro Shimizu |
890ddd |
splitPoint = i;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return maxErr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double NewtonRaphsonRootFind3D(const TThickCubic &cubic, const T3DPointD &p3D, double u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TPointD qU = cubic.getPoint(u);
|
|
Toshihiro Shimizu |
890ddd |
TPointD q1U = cubic.getSpeed(u);
|
|
Toshihiro Shimizu |
890ddd |
TPointD q2U = cubic.getAcceleration(u);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD p(p3D.x, p3D.y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return u - ((qU - p) * q1U) / (norm2(q1U) + (qU - p) * q2U);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int compareDouble(const void *e1, const void *e2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return (*(double *)e1 < *(double *)e2) ? -1 : (*(double *)e1 == *(double *)e2) ? 0 : 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double *reparameterize3D(const TThickCubic &cubic,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD *pointsArrayBegin,
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
double *u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double *uPrime = new double[size];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < size; i++) {
|
|
Toshihiro Shimizu |
890ddd |
uPrime[i] = NewtonRaphsonRootFind3D(cubic, *(pointsArrayBegin + i), u[i]);
|
|
Toshihiro Shimizu |
890ddd |
if (!_finite(uPrime[i])) {
|
|
Toshihiro Shimizu |
890ddd |
delete uPrime;
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
qsort(uPrime, size, sizeof(double), compareDouble);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (uPrime[0] < 0.0 || uPrime[size - 1] > 1.0) {
|
|
Toshihiro Shimizu |
890ddd |
delete uPrime;
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(uPrime[0] >= 0.0);
|
|
Toshihiro Shimizu |
890ddd |
assert(uPrime[size - 1] <= 1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return uPrime;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline double B1(double u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double tmp = 1.0 - u;
|
|
Toshihiro Shimizu |
890ddd |
return 3 * u * tmp * tmp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
inline double B2(double u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return 3 * u * u * (1 - u);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
inline double B0plusB1(double u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double tmp = 1.0 - u;
|
|
Toshihiro Shimizu |
890ddd |
return tmp * tmp * (1.0 + 2.0 * u);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
inline double B2plusB3(double u)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return u * u * (3.0 - 2.0 * u);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TCubicStroke
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic *generateCubic3D(const T3DPointD pointsArrayBegin[],
|
|
Toshihiro Shimizu |
890ddd |
const double uPrime[],
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentRight);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Genera una cubica in modo ricorsivo
|
|
Toshihiro Shimizu |
890ddd |
void fitCubic3D(const T3DPointD pointsArrayBegin[],
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentRight,
|
|
Toshihiro Shimizu |
890ddd |
double error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD m_bBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickcubic *=""> *m_cubicChunkArray;</tthickcubic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Costruisce un TCubicStroke uguale al TCubicStroke datogli
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke(const TCubicStroke &stroke);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Costruisce un TCubicStroke da un array di T3DPointD,
|
|
Toshihiro Shimizu |
890ddd |
in funzione dei due parametri error e doDetectCorners
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke(const vector<t3dpointd> &pointsArray3D,</t3dpointd>
|
|
Toshihiro Shimizu |
890ddd |
double error, bool doDetectCorners = true);
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke( vector<tpointd> &pointsArray, </tpointd>
|
|
Toshihiro Shimizu |
890ddd |
double error,
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &tangentRight);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~TCubicStroke();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
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 |
/*! It splits a cubic bezier curve 'splits' times in the half. Then each
|
|
Toshihiro Shimizu |
890ddd |
subcurve is converted into quadratic curve, computing the middle control
|
|
Toshihiro Shimizu |
890ddd |
circle as the weighted averege of the four control circles of the
|
|
Toshihiro Shimizu |
890ddd |
original cubic subcurve.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void doComputeQuadraticsFromCubic(const TThickCubic &cubic,
|
|
Toshihiro Shimizu |
890ddd |
int splits,
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickquadratic *=""> &chunkArray)</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p0r, p1r, p2r, p3r, p0l, p1l, p2l, p3l;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p0l = cubic.getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
p1l = cubic.getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
p2l = cubic.getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
p3l = cubic.getThickP3();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p3l = 0.5 * (p3l + p2l);
|
|
Toshihiro Shimizu |
890ddd |
p2l = 0.5 * (p2l + p1l);
|
|
Toshihiro Shimizu |
890ddd |
p1l = 0.5 * (p1l + p0l);
|
|
Toshihiro Shimizu |
890ddd |
p3l = 0.5 * (p3l + p2l);
|
|
Toshihiro Shimizu |
890ddd |
p2l = 0.5 * (p2l + p1l);
|
|
Toshihiro Shimizu |
890ddd |
p3l = 0.5 * (p3l + p2l);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p0r = cubic.getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
p1r = cubic.getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
p2r = cubic.getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
p3r = cubic.getThickP3();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
p0r = 0.5 * (p0r + p1r);
|
|
Toshihiro Shimizu |
890ddd |
p1r = 0.5 * (p1r + p2r);
|
|
Toshihiro Shimizu |
890ddd |
p2r = 0.5 * (p2r + p3r);
|
|
Toshihiro Shimizu |
890ddd |
p0r = 0.5 * (p0r + p1r);
|
|
Toshihiro Shimizu |
890ddd |
p1r = 0.5 * (p1r + p2r);
|
|
Toshihiro Shimizu |
890ddd |
p0r = 0.5 * (p0r + p1r);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (splits > 0) {
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic cubic1(cubic);
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic tmp_1(p0l, p1l, p2l, p3l);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(cubic1, tmp_1);
|
|
Toshihiro Shimizu |
890ddd |
doComputeQuadraticsFromCubic(cubic1, splits - 1, chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic tmp_2(p0r, p1r, p2r, p3r);
|
|
Toshihiro Shimizu |
890ddd |
std::swap(cubic1, tmp_2);
|
|
Toshihiro Shimizu |
890ddd |
doComputeQuadraticsFromCubic(cubic1, splits - 1, chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *chunkL = new TThickQuadratic(p0l, 0.25 * (3 * (p1l + p2l) - (p0l + p3l)), p3l);
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *chunkR = new TThickQuadratic(p0r, 0.25 * (3 * (p1r + p2r) - (p0r + p3r)), p3r);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(chunkL);
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(chunkR);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Genera una o piu' quadratiche da una cubica.
|
|
Toshihiro Shimizu |
890ddd |
Pone una serie di condizioni , se sono verificate crea una unica quadratica,
|
|
Toshihiro Shimizu |
890ddd |
altrimenti richiama doComputeQuadraticsFromCubic
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
void computeQuadraticsFromCubic(const TThickCubic &cubic,
|
|
Toshihiro Shimizu |
890ddd |
double error,
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickquadratic *=""> &chunkArray)</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
const double T = 0.21132486540518711775;
|
|
Toshihiro Shimizu |
890ddd |
const double S = (1 - T);
|
|
Toshihiro Shimizu |
890ddd |
int splits;
|
|
Toshihiro Shimizu |
890ddd |
double dist2 = tdistance2(cubic.getP1(), cubic.getP2());
|
|
Toshihiro Shimizu |
890ddd |
if (dist2 < 2) {
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(new TThickQuadratic(cubic.getThickP0(), 0.5 * (cubic.getThickP1() + cubic.getThickP2()), cubic.getThickP3()));
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD dp = ((S * S * S) - (S * S - S * T / 2)) * cubic.getP0() +
|
|
Toshihiro Shimizu |
890ddd |
((3 * S * S * T) - (S * T * 3 / 2)) * cubic.getP1() +
|
|
Toshihiro Shimizu |
890ddd |
((3 * S * T * T) - (S * T * 3 / 2)) * cubic.getP2() +
|
|
Toshihiro Shimizu |
890ddd |
((T * T * T) - (T * T - S * T / 2)) * cubic.getP3();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double dist_sq = norm2(dp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (splits = 0; dist_sq > error; splits++)
|
|
Toshihiro Shimizu |
890ddd |
dist_sq *= 0.125 * 0.125;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (splits == 0) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD p0 = cubic.getP0();
|
|
Toshihiro Shimizu |
890ddd |
TPointD p1 = cubic.getP1();
|
|
Toshihiro Shimizu |
890ddd |
TPointD p2 = cubic.getP2();
|
|
Toshihiro Shimizu |
890ddd |
TPointD p3 = cubic.getP3();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD side01 = p1 - p0;
|
|
Toshihiro Shimizu |
890ddd |
TPointD side32 = p2 - p3;
|
|
Toshihiro Shimizu |
890ddd |
// se sono verificate TUTTE le condizioni dei seguenti if nidificati, allora viene
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// se NON viene verificata ALMENO una delle condizioni dei seguenti if nidificati, allora
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double det = -side01.x * side32.y + side01.y * side32.x;
|
|
Toshihiro Shimizu |
890ddd |
if (!isAlmostZero(det)) // side01 incidente side32 (verra' calcolata l'intersezione...)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TPointD side03 = p3 - p0;
|
|
Toshihiro Shimizu |
890ddd |
double det01 = -side03.x * side32.y + side03.y * side32.x;
|
|
Toshihiro Shimizu |
890ddd |
double det32 = side01.x * side03.y - side01.y * side03.x;
|
|
Toshihiro Shimizu |
890ddd |
double t01 = det01 / det;
|
|
Toshihiro Shimizu |
890ddd |
double t32 = det32 / det;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
TPointD p01 = p0 + t01*(p1 - p0);
|
|
Toshihiro Shimizu |
890ddd |
TPointD p32 = p3 + t32*(p2 - p3);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (t01 >= 1 && t32 >= 1) {
|
|
Toshihiro Shimizu |
890ddd |
double norm2_side0p = norm2(t01 * side01);
|
|
Toshihiro Shimizu |
890ddd |
double norm2_side3p = norm2(t32 * side32);
|
|
Toshihiro Shimizu |
890ddd |
if (!isAlmostZero(norm2_side0p, 1e-20) && !isAlmostZero(norm2_side3p, 1e-20)) {
|
|
Toshihiro Shimizu |
890ddd |
double norm2_side03 = norm2(side03);
|
|
Toshihiro Shimizu |
890ddd |
double tmp = norm2_side0p + norm2_side3p - norm2_side03;
|
|
Toshihiro Shimizu |
890ddd |
//double cs = tmp/(2*sqrt(norm2_side0p)*sqrt(norm2_side3p)); // debug
|
|
Toshihiro Shimizu |
890ddd |
double cs_sign = tmp >= 0 ? 1 : -1;
|
|
Toshihiro Shimizu |
890ddd |
// th coseno: gli assert del tipo acos(sqrt(cs2)) sono commentati perche' puo' essere cs2 > 1 per errori
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double cs2 = sq(tmp) / (4 * norm2_side0p * norm2_side3p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(areAlmostEqual(tsign(cs_sign) * sqrt(cs2), tmp / (2 * sqrt(norm2_side0p) * sqrt(norm2_side3p))));
|
|
Shinya Kitaoka |
ee259f |
assert(!(cs_sign < 0) || acos(-sqrt(cs2)) > 10 * M_PI_180); // cs_sign < 0 => acos(-sqrt(cs2)) > 10°
|
|
Toshihiro Shimizu |
890ddd |
if (cs_sign < 0 || cs2 < 0.969846)
|
|
Toshihiro Shimizu |
890ddd |
{ // limita distanza di intersection: elimina quadratiche "cappio" (con p1 "lontano")
|
|
Shinya Kitaoka |
ee259f |
//assert (acos(tsign(cs_sign)*sqrt(cs2)) > 10*M_PI_180);
|
|
Shinya Kitaoka |
ee259f |
assert(tsign(cs_sign) * sqrt(cs2) < cos(10 * M_PI_180));
|
|
Toshihiro Shimizu |
890ddd |
TPointD intersection = p0 + t01 * (p1 - p0);
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p(intersection.x, intersection.y, 0.5 * (cubic.getThickP1().thick + cubic.getThickP2().thick));
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(new TThickQuadratic(cubic.getThickP0(), p, cubic.getThickP3()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
TThickQuadratic *lastTq = chunkArray.back();
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint pDeb = lastTq->getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.thick));
|
|
Toshihiro Shimizu |
890ddd |
pDeb = lastTq->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.thick));
|
|
Toshihiro Shimizu |
890ddd |
pDeb = lastTq->getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(pDeb.thick));
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
numSaved++;
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
TPointD side03 = p3 - p0;
|
|
Toshihiro Shimizu |
890ddd |
double det01 = -side03.x * side32.y + side03.y * side32.x;
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(det01)) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
chunkArray.push_back(new TThickQuadratic(
|
|
Toshihiro Shimizu |
890ddd |
cubic.getThickP0(),
|
|
Toshihiro Shimizu |
890ddd |
(cubic.getThickP1() + cubic.getThickP2()) * 0.5,
|
|
Toshihiro Shimizu |
890ddd |
cubic.getThickP3()));
|
|
Toshihiro Shimizu |
890ddd |
numSaved++;
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//else: se arriva qui, almeno una delle condizioni negli if nidificati precedenti e' falsa
|
|
Toshihiro Shimizu |
890ddd |
splits++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
doComputeQuadraticsFromCubic(cubic, splits - 1, chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *computeQuadStroke(const TCubicStroke &cubic)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickquadratic *=""> chunkArray;</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < cubic.m_cubicChunkArray->size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic tmp(*(*cubic.m_cubicChunkArray)[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p = tmp.getThickP0();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.thick));
|
|
Toshihiro Shimizu |
890ddd |
p = tmp.getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.thick));
|
|
Toshihiro Shimizu |
890ddd |
p = tmp.getThickP2();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.thick));
|
|
Toshihiro Shimizu |
890ddd |
p = tmp.getThickP3();
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.thick));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// this code use a Chebychev version of degree reduction
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// This code is for old algorithm only:
|
|
Toshihiro Shimizu |
890ddd |
computeQuadraticsFromCubic(tmp, 2.0 , chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *outStroke = TStroke::create(chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
clearPointerContainer(chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return outStroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// helper function (defined in tstroke.h)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void computeQuadraticsFromCubic(const TThickPoint &p0,
|
|
Toshihiro Shimizu |
890ddd |
const TThickPoint &p1,
|
|
Toshihiro Shimizu |
890ddd |
const TThickPoint &p2,
|
|
Toshihiro Shimizu |
890ddd |
const TThickPoint &p3,
|
|
Toshihiro Shimizu |
890ddd |
double error,
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickquadratic *=""> &chunkArray)</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
computeQuadraticsFromCubic(TThickCubic(p0, p1, p2, p3), error, chunkArray);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke::TCubicStroke()
|
|
Toshihiro Shimizu |
890ddd |
: m_bBox()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray = new TThickCubicArray();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke::TCubicStroke(const TCubicStroke &stroke)
|
|
Toshihiro Shimizu |
890ddd |
: m_bBox(stroke.m_bBox), m_cubicChunkArray(stroke.m_cubicChunkArray)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray = new TThickCubicArray(*stroke.m_cubicChunkArray);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke::~TCubicStroke()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_cubicChunkArray) {
|
|
Toshihiro Shimizu |
890ddd |
while (!m_cubicChunkArray->empty()) {
|
|
Toshihiro Shimizu |
890ddd |
delete m_cubicChunkArray->back();
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray->pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete m_cubicChunkArray;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke::TCubicStroke(const vector<t3dpointd> &pointsArray3D,</t3dpointd>
|
|
Toshihiro Shimizu |
890ddd |
double error, bool doDetectCorners)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<int> corners;</int>
|
|
Toshihiro Shimizu |
890ddd |
corners.push_back(0);
|
|
Toshihiro Shimizu |
890ddd |
if (doDetectCorners)
|
|
Toshihiro Shimizu |
890ddd |
detectCorners(pointsArray3D, 3, 3, 15, 100, corners);
|
|
Toshihiro Shimizu |
890ddd |
corners.push_back(pointsArray3D.size() - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef USE_NEW_3D_ERROR_COMPUTE
|
|
Toshihiro Shimizu |
890ddd |
error *= error;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray = new vector<tthickcubic *="">();</tthickcubic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 1; i < (int)corners.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
int size = corners[i] - corners[i - 1] + 1;
|
|
Toshihiro Shimizu |
890ddd |
int firstPoint = corners[i - 1];
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD
|
|
Toshihiro Shimizu |
890ddd |
tanLeft,
|
|
Toshihiro Shimizu |
890ddd |
tanRigth;
|
|
Toshihiro Shimizu |
890ddd |
assert(size > 0);
|
|
Toshihiro Shimizu |
890ddd |
if (size > 1) // capita che corners[i] = corners[i - 1] ("clic" senza drag oppure bug (noto!!!) del cornerDetector)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
tanLeft = -pointsArray3D[firstPoint + 1] + pointsArray3D[firstPoint];
|
|
Toshihiro Shimizu |
890ddd |
tanRigth = pointsArray3D[firstPoint + size - 2] - pointsArray3D[firstPoint + size - 1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (norm2(tanLeft) > 0)
|
|
Toshihiro Shimizu |
890ddd |
tanLeft = normalize(tanLeft);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (norm2(tanRigth) > 0)
|
|
Toshihiro Shimizu |
890ddd |
tanRigth = normalize(tanRigth);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fitCubic3D(
|
|
Toshihiro Shimizu |
890ddd |
&pointsArray3D[firstPoint],
|
|
Toshihiro Shimizu |
890ddd |
size,
|
|
Toshihiro Shimizu |
890ddd |
tanLeft,
|
|
Toshihiro Shimizu |
890ddd |
tanRigth,
|
|
Toshihiro Shimizu |
890ddd |
error);
|
|
Toshihiro Shimizu |
890ddd |
} else if (pointsArray3D.size() == 1) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// e finale coincidenti: 1 solo punto campionato ("clic" senza drag)
|
|
Toshihiro Shimizu |
890ddd |
assert(size == 1);
|
|
Toshihiro Shimizu |
890ddd |
assert(corners.size() == 2);
|
|
Toshihiro Shimizu |
890ddd |
assert(corners[0] == 0);
|
|
Toshihiro Shimizu |
890ddd |
assert(corners[1] == 0);
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray->push_back(new TThickCubic(pointsArray3D[0],
|
|
Toshihiro Shimizu |
890ddd |
pointsArray3D[0],
|
|
Toshihiro Shimizu |
890ddd |
pointsArray3D[0],
|
|
Toshihiro Shimizu |
890ddd |
pointsArray3D[0]));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TCubicStroke::fitCubic3D(const T3DPointD pointsArrayBegin[],
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentRight,
|
|
Toshihiro Shimizu |
890ddd |
double error)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int maxIterations = 4;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (size == 2) {
|
|
Toshihiro Shimizu |
890ddd |
double dist = tdistance(*pointsArrayBegin, *(pointsArrayBegin + 1)) / 3.0;
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic *strokeCubicChunk = new TThickCubic(*pointsArrayBegin,
|
|
Toshihiro Shimizu |
890ddd |
*pointsArrayBegin - dist * tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
*(pointsArrayBegin + 1) + dist * tangentRight,
|
|
Toshihiro Shimizu |
890ddd |
*(pointsArrayBegin + 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray->push_back(strokeCubicChunk);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double *u = chordLengthParameterize3D(pointsArrayBegin, size);
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic *cubic = generateCubic3D(pointsArrayBegin, u, size, tangentLeft, tangentRight);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int splitPoint;
|
|
Toshihiro Shimizu |
890ddd |
double maxError = computeMaxError3D(*cubic, pointsArrayBegin, size, u, splitPoint);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (maxError < error) {
|
|
Toshihiro Shimizu |
890ddd |
delete[] u;
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray->push_back(cubic);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//if (maxError
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double *uPrime = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < maxIterations; i++) {
|
|
Toshihiro Shimizu |
890ddd |
//delete uPrime;
|
|
Toshihiro Shimizu |
890ddd |
uPrime = reparameterize3D(*cubic, pointsArrayBegin, size, u);
|
|
Toshihiro Shimizu |
890ddd |
if (!uPrime)
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete cubic;
|
|
Toshihiro Shimizu |
890ddd |
cubic = generateCubic3D(pointsArrayBegin, uPrime, size, tangentLeft, tangentRight);
|
|
Toshihiro Shimizu |
890ddd |
maxError = computeMaxError3D(*cubic, pointsArrayBegin, size, uPrime, splitPoint);
|
|
Toshihiro Shimizu |
890ddd |
if (maxError < error) {
|
|
Toshihiro Shimizu |
890ddd |
delete uPrime;
|
|
Toshihiro Shimizu |
890ddd |
delete[] u;
|
|
Toshihiro Shimizu |
890ddd |
m_cubicChunkArray->push_back(cubic);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
delete[] u;
|
|
Toshihiro Shimizu |
890ddd |
u = uPrime;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete[] u;
|
|
Toshihiro Shimizu |
890ddd |
delete cubic;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD centralTangent;
|
|
Toshihiro Shimizu |
890ddd |
if (*(pointsArrayBegin + splitPoint - 1) == *(pointsArrayBegin + splitPoint + 1))
|
|
Toshihiro Shimizu |
890ddd |
centralTangent = normalize(*(pointsArrayBegin + splitPoint) - *(pointsArrayBegin + splitPoint + 1));
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
centralTangent = normalize(*(pointsArrayBegin + splitPoint - 1) - *(pointsArrayBegin + splitPoint + 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fitCubic3D(pointsArrayBegin, splitPoint + 1, tangentLeft, centralTangent, error);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
fitCubic3D(pointsArrayBegin + splitPoint, size - splitPoint, centralTangent, tangentRight, error);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic *TCubicStroke::generateCubic3D(const T3DPointD pointsArrayBegin[],
|
|
Toshihiro Shimizu |
890ddd |
const double uPrime[],
|
|
Toshihiro Shimizu |
890ddd |
int size,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentLeft,
|
|
Toshihiro Shimizu |
890ddd |
const T3DPointD &tangentRight)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double X[2], C[2][2];
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD p0 = *pointsArrayBegin;
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD p3 = *(pointsArrayBegin + size - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
C[0][0] = C[0][1] = X[0] = 0;
|
|
Toshihiro Shimizu |
890ddd |
C[1][0] = C[1][1] = X[1] = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; i++) {
|
|
Campbell Barton |
5db682 |
const T3DPointD A[2] = {
|
|
Campbell Barton |
5db682 |
tangentLeft * B1(uPrime[i]),
|
|
Campbell Barton |
5db682 |
tangentRight * B2(uPrime[i]),
|
|
Campbell Barton |
5db682 |
};
|
|
Campbell Barton |
5db682 |
|
|
Campbell Barton |
5db682 |
C[0][0] += A[0] * A[0];
|
|
Campbell Barton |
5db682 |
C[0][1] += A[0] * A[1];
|
|
Campbell Barton |
5db682 |
C[1][1] += A[1] * A[1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
C[1][0] = C[0][1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD tmp = *(pointsArrayBegin + i) - (B0plusB1(uPrime[i]) * p0) +
|
|
Toshihiro Shimizu |
890ddd |
B2plusB3(uPrime[i]) * p3;
|
|
Campbell Barton |
5db682 |
X[0] += A[0] * tmp;
|
|
Campbell Barton |
5db682 |
X[1] += A[1] * tmp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double detC0C1 = C[0][0] * C[1][1] - C[0][1] * C[1][0];
|
|
Toshihiro Shimizu |
890ddd |
double detC0X = X[1] * C[0][0] - X[0] * C[0][1];
|
|
Toshihiro Shimizu |
890ddd |
double detXC1 = X[0] * C[1][1] - X[1] * C[0][1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(detC0C1))
|
|
Toshihiro Shimizu |
890ddd |
detC0C1 = C[0][0] * C[1][1] * 10e-12;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double alphaL = detXC1 / detC0C1;
|
|
Toshihiro Shimizu |
890ddd |
double alphaR = detC0X / detC0C1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Intanto bisognerebbe accertarsi che 'sti valori alcune volte sono cosi' assurdi solo per problemi
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double xmin = (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
double ymin = (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
double xmax = -(numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
double ymax = -(numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
double thickmin = (numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
double thickmax = -(numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; i++) {
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].x < xmin)
|
|
Toshihiro Shimizu |
890ddd |
xmin = pointsArrayBegin[i].x;
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].x > xmax)
|
|
Toshihiro Shimizu |
890ddd |
xmax = pointsArrayBegin[i].x;
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].y < ymin)
|
|
Toshihiro Shimizu |
890ddd |
ymin = pointsArrayBegin[i].y;
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].y > ymax)
|
|
Toshihiro Shimizu |
890ddd |
ymax = pointsArrayBegin[i].y;
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].z < thickmin)
|
|
Toshihiro Shimizu |
890ddd |
thickmin = pointsArrayBegin[i].z;
|
|
Toshihiro Shimizu |
890ddd |
if (pointsArrayBegin[i].z > thickmax)
|
|
Toshihiro Shimizu |
890ddd |
thickmax = pointsArrayBegin[i].z;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double lx = xmax - xmin;
|
|
Toshihiro Shimizu |
890ddd |
assert(lx >= 0);
|
|
Toshihiro Shimizu |
890ddd |
double ly = ymax - ymin;
|
|
Toshihiro Shimizu |
890ddd |
assert(ly >= 0);
|
|
Toshihiro Shimizu |
890ddd |
double lt = thickmax - thickmin;
|
|
Toshihiro Shimizu |
890ddd |
assert(lt >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
xmin -= lx;
|
|
Toshihiro Shimizu |
890ddd |
xmax += lx;
|
|
Toshihiro Shimizu |
890ddd |
ymin -= ly;
|
|
Toshihiro Shimizu |
890ddd |
ymax += ly;
|
|
Toshihiro Shimizu |
890ddd |
thickmin -= lt;
|
|
Toshihiro Shimizu |
890ddd |
thickmax += lt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox(xmin, ymin, xmax, ymax);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (alphaL < 0.0 || alphaR < 0.0)
|
|
Toshihiro Shimizu |
890ddd |
alphaL = alphaR = sqrt(tdistance2(p0, p3)) / 3.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD p1 = p0 - tangentLeft * alphaL;
|
|
Toshihiro Shimizu |
890ddd |
T3DPointD p2 = p3 + tangentRight * alphaR;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!bbox.contains(TPointD(p1.x, p1.y)) ||
|
|
Toshihiro Shimizu |
890ddd |
!bbox.contains(TPointD(p2.x, p2.y))) {
|
|
Toshihiro Shimizu |
890ddd |
alphaL = alphaR = sqrt(tdistance2(p0, p3)) / 3.0;
|
|
Toshihiro Shimizu |
890ddd |
p1 = p0 - tangentLeft * alphaL;
|
|
Toshihiro Shimizu |
890ddd |
p2 = p3 + tangentRight * alphaR;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (p1.z < thickmin)
|
|
Toshihiro Shimizu |
890ddd |
p1.z = thickmin;
|
|
Toshihiro Shimizu |
890ddd |
else if (p1.z > thickmax)
|
|
Toshihiro Shimizu |
890ddd |
p1.z = thickmax;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (p2.z < thickmin)
|
|
Toshihiro Shimizu |
890ddd |
p2.z = thickmin;
|
|
Toshihiro Shimizu |
890ddd |
else if (p2.z > thickmax)
|
|
Toshihiro Shimizu |
890ddd |
p2.z = thickmax;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TThickCubic *thickCubic = new TThickCubic(TThickPoint(p0.x, p0.y, p0.z),
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint(p1.x, p1.y, p1.z),
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint(p2.x, p2.y, p2.z),
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint(p3.x, p3.y, p3.z));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return thickCubic;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Trasforma un vettore di TThickPoint in un vettore di T3DPointD che usa per trovare un
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke, cioe' uno stroke cubico. Da questo trova lo stroke quadratico.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TStroke *TStroke::interpolate(const vector<tthickpoint> &points, double error, bool findCorners)</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
vector<t3dpointd> pointsArray3D;</t3dpointd>
|
|
Toshihiro Shimizu |
890ddd |
convert(points, pointsArray3D);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TCubicStroke cubicStroke(pointsArray3D, error, findCorners);
|
|
Toshihiro Shimizu |
890ddd |
numSaved = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke = computeQuadStroke(cubicStroke);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT cpIndex = 0;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p;
|
|
Toshihiro Shimizu |
890ddd |
for (; cpIndex != (UINT)stroke->getControlPointCount(); cpIndex++) {
|
|
Toshihiro Shimizu |
890ddd |
p = stroke->getControlPoint(cpIndex);
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.x));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.y));
|
|
Toshihiro Shimizu |
890ddd |
assert(_finite(p.thick));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
removeNullQuadratic(stroke);
|
|
Toshihiro Shimizu |
890ddd |
stroke->invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return stroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Estrae dalle curve i punti di controllo e crea con questi un nuovo stroke
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
TStroke *TStroke::create(const vector<tthickquadratic *=""> &curves)</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (curves.empty())
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vector<tthickpoint> ctrlPnts;</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
extractStrokeControlPoints(curves, ctrlPnts);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke = new TStroke(ctrlPnts);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
stroke->invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return stroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStrokeProp::TStrokeProp(const TStroke *stroke)
|
|
Toshihiro Shimizu |
890ddd |
: m_stroke(stroke), m_strokeChanged(true), m_mutex()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::OutlineOptions::OutlineOptions()
|
|
Toshihiro Shimizu |
890ddd |
: m_capStyle(ROUND_CAP), m_joinStyle(ROUND_JOIN), m_miterLower(0.0), m_miterUpper(4.0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke::OutlineOptions::OutlineOptions(
|
|
Toshihiro Shimizu |
890ddd |
UCHAR capStyle, UCHAR joinStyle, double lower, double upper)
|
|
Toshihiro Shimizu |
890ddd |
: m_capStyle(capStyle), m_joinStyle(joinStyle), m_miterLower(lower), m_miterUpper(upper)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|