示例#1
0
		int isAscending(const TThickQuadratic &q, double t, bool forward)
		{
			double y0 = y(q.getP0()), y1 = y(q.getP1()), y2 = y(q.getP2()),
				   y1_y0 = y1 - y0, y2_y1 = y2 - y1;

			double yspeed_2 = tcg::numeric_ops::lerp(y1_y0, y2_y1, t) * (2 * int(forward) - 1),
				   yaccel = y2_y1 - y1_y0;

			return (yspeed_2 > 0.0) ? 1
									: (yspeed_2 < 0.0) ? -1
													   : tcg::numeric_ops::sign(yaccel);
		}
示例#2
0
double computeStep(const TThickQuadratic &quad, double pixelSize) {
  TThickPoint cp0 = quad.getThickP0(), cp1 = quad.getThickP1(),
              cp2 = quad.getThickP2();

  TQuadratic q1(TPointD(cp0.x, cp0.y), TPointD(cp1.x, cp1.y),
                TPointD(cp2.x, cp2.y)),
      q2(TPointD(cp0.y, cp0.thick), TPointD(cp1.y, cp1.thick),
         TPointD(cp2.y, cp2.thick)),
      q3(TPointD(cp0.x, cp0.thick), TPointD(cp1.x, cp1.thick),
         TPointD(cp2.x, cp2.thick));

  return std::min({computeStep(q1, pixelSize), computeStep(q2, pixelSize),
                   computeStep(q3, pixelSize)});
}
void makeOutline(const TStroke *stroke, int startQuad, int endQuad,
				 outlineBoundary &ob, double error2)
{
	//std::ofstream cout("c:\\temp\\outline.txt");

	assert(stroke);
	assert(startQuad >= 0);
	assert(endQuad < stroke->getChunkCount());
	assert(startQuad <= endQuad);
	TThickQuadratic *tq;
	std::vector<TQuadratic *> arrayUp, arrayDown;
	TQuadratic arc;

	if (!stroke->getChunkCount())
		return;
	//if (startQuad==0)
	{
		const TThickQuadratic *tq = stroke->getChunk(startQuad);

		// trova i punti sul cerchio che corrispondono
		// a due fette di 90 gradi.
		// Ritorna una quadratica invece di tre singoli punti solo per compattezza.
		TQuadratic
			arc = getCircleQuarter(tq, QUARTER_BEGIN);

		// estrae le quadratiche che corrispondono ad i due archi...
		splitCircularArcIntoQuadraticCurves(tq->getP0(), arc.getP0(), arc.getP1(), arrayUp);
		// e le ordina in modo che l'outline sia composta sempre da
		// una curva superiore ed una inferiore corrispondente
		changeDirection(arrayUp);
		splitCircularArcIntoQuadraticCurves(tq->getP0(), arc.getP1(), arc.getP2(), arrayDown);
		changeDirection(arrayDown, true);
		// copia le curve nell'outline; se gli array non hanno la stessa dimensione
		//  quello con meno curve viene riempito con curve improprie
		//  che hanno i punti di controllo coincidente con l'ultimo estremo valido
		//cout<<"quads del semicerchio left:"<<std::endl;
		copy(/*cout,  */ arrayUp, arrayDown, ob);
	}

	for (int i = startQuad; i <= endQuad; ++i) {
		tq = (TThickQuadratic *)stroke->getChunk(i);
		TThickPoint p0 = tq->getThickP0();
		TThickPoint p1 = tq->getThickP1();
		TThickPoint p2 = tq->getThickP2();
		if (p0.x == p1.x) {
			if (p1.x == p2.x && ((p1.y > p0.y && p1.y > p2.y) || (p1.y < p0.y && p1.y < p2.y)))
				tq = new TThickQuadratic(p0, 0.5 * (p0 + p1), p1);
		} else if (p0.y == p1.y) {
			if (p0.y == p2.y && ((p1.x > p0.x && p1.x > p2.x) || (p1.x < p0.x && p1.x < p2.x)))
				tq = new TThickQuadratic(p0, 0.5 * (p0 + p1), p1);
		} else {
			double fac1 = 1.0 / (p0.x - p1.x);
			double fac2 = 1.0 / (p0.y - p1.y);

			double aux1 = fac1 * (p2.x - p1.x);
			double aux2 = fac2 * (p2.y - p1.y);
			double aux3 = fac1 * (p0.x - p2.x);
			double aux4 = fac2 * (p0.y - p2.y);

			if ((areAlmostEqual(aux1, aux2) && aux1 >= 0) ||
				(areAlmostEqual(aux3, aux4) && aux3 >= 0 && aux3 <= 1))
				tq = new TThickQuadratic(p0, 0.5 * (p0 + p1), p1);
		}

		//cout<<"quad# "<<i<<":" <<*tq<<std::endl;
		makeOutline(/*cout, */ ob, *tq, error2);
		if (tq != stroke->getChunk(i))
			delete tq;
	}

	arrayUp.clear();
	arrayDown.clear();

	// come sopra ultimo pezzo di arco
	//	if (endQuad==stroke->getChunkCount()-1)
	{
		arc = getCircleQuarter(tq, QUARTER_END);
		splitCircularArcIntoQuadraticCurves(tq->getP2(), arc.getP1(), arc.getP0(), arrayUp);
		changeDirection(arrayUp);
		splitCircularArcIntoQuadraticCurves(tq->getP2(), arc.getP2(), arc.getP1(), arrayDown);
		changeDirection(arrayDown, true);
		//cout<<"quads del semicerchio right:"<<std::endl;

		copy(/*cout,*/ arrayUp, arrayDown, ob);
	}
}