Пример #1
0
void TRegion::Imp::computeScanlineIntersections(double y, vector<double> &intersections) const
{
	TRectD bbox = getBBox();
	if (y <= bbox.y0 || y >= bbox.y1)
		return;

	assert(intersections.empty());

	UINT i, firstSide = 0;
	vector<int> sides;

	for (i = 0; i < m_edge.size(); i++) {
		TEdge *e = m_edge[i];

		TStroke *s = e->m_s;
		if (s->getBBox().y0 > y || s->getBBox().y1 < y)
			continue;
		int chunkIndex0, chunkIndex1;
		double t0, t1;
		s->getChunkAndT(e->m_w0, chunkIndex0, t0);
		s->getChunkAndT(e->m_w1, chunkIndex1, t1);

		if (chunkIndex0 > chunkIndex1) {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, 0, intersections, sides);
			for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
				findIntersections(y, *s->getChunk(j), 1, 0, intersections, sides);
			findIntersections(y, *s->getChunk(chunkIndex1), 1, t1, intersections, sides);
		} else if (chunkIndex0 < chunkIndex1) {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, 1, intersections, sides);
			for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
				findIntersections(y, *s->getChunk(j), 0, 1, intersections, sides);
			findIntersections(y, *s->getChunk(chunkIndex1), 0, t1, intersections, sides);
		} else {
			findIntersections(y, *s->getChunk(chunkIndex0), t0, t1, intersections, sides);
		}
	}

	if (intersections.size() > 0 && intersections.front() == intersections.back()) {
		intersections.pop_back();
		if (!sides.empty() && sides.front() == sides.back() && intersections.size() > 0)
			intersections.erase(intersections.begin());
	}

	std::sort(intersections.begin(), intersections.end());
	assert(intersections.size() % 2 == 0);
}
Пример #2
0
//-----------------------------------------------------------------------------
bool TRegion::Imp::contains(const TPointD &p) const
{
	bool leftAreOdd = false;

	if (!getBBox().contains(p))
		return false;

	//printContains(p);

	UINT i;

	int side = 0;

	for (i = 0; i < m_edge.size() * 2; i++) //i pari, esplora gli edge,
											//i dispari esplora i segmenti di autoclose tra un edge e il successivo
	{
		if (i & 0x1) {
			TPointD p0 = m_edge[i / 2]->m_s->getPoint(m_edge[i / 2]->m_w1);
			TPointD p1;
			if (i / 2 < m_edge.size() - 1)
				p1 = m_edge[i / 2 + 1]->m_s->getPoint(m_edge[i / 2 + 1]->m_w0);
			else
				p1 = m_edge[0]->m_s->getPoint(m_edge[0]->m_w0);

			if (tmin(p0.y, p1.y) > p.y || tmax(p0.y, p1.y) < p.y)
				continue;

			if (!areAlmostEqual(p0, p1, 1e-2))
				side = findSides(p, TQuadratic(p0, 0.5 * (p0 + p1), p1), 0.0, 1.0, leftAreOdd, side);

			continue;
		}

		TEdge *e = m_edge[i / 2];

		TStroke *s = e->m_s;
		if (s->getBBox().y0 > p.y || s->getBBox().y1 < p.y)
			continue;

		double t0, t1;
		int chunkIndex0, chunkIndex1;
		const TThickQuadratic *q0, *q1;

		s->getChunkAndT(e->m_w0, chunkIndex0, t0);
		s->getChunkAndT(e->m_w1, chunkIndex1, t1);
		q0 = s->getChunk(chunkIndex0);
		q1 = s->getChunk(chunkIndex1);

		if (i == 0 && areAlmostEqual(q0->getPoint(t0).y, p.y)) {
			double tEnd;
			int chunkIndexEnd;
			TEdge *edgeEnd = m_edge.back();
			edgeEnd->m_s->getChunkAndT(edgeEnd->m_w1, chunkIndexEnd, tEnd);
			assert(areAlmostEqual(edgeEnd->m_s->getChunk(chunkIndexEnd)->getPoint(tEnd).y, p.y));
			side = edgeEnd->m_s->getChunk(chunkIndexEnd)->getSpeed(tEnd).y > 0 ? 1 : -1;
		}

		if (chunkIndex0 != chunkIndex1) {
			/*if (chunkIndex0>chunkIndex1)
		  {
		  tswap(chunkIndex0, chunkIndex1);
		  tswap(t0, t1);
      }*/
			if (chunkIndex0 > chunkIndex1) {
				side = findSides(p, *q0, t0, 0, leftAreOdd, side);
				for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
					side = findSides(p, *s->getChunk(j), 1, 0, leftAreOdd, side);
				side = findSides(p, *q1, 1, t1, leftAreOdd, side);
			} else {
				side = findSides(p, *q0, t0, 1, leftAreOdd, side);
				for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
					side = findSides(p, *s->getChunk(j), 0, 1, leftAreOdd, side);
				side = findSides(p, *q1, 0, t1, leftAreOdd, side);
			}

		} else
			side = findSides(p, *q0, t0, t1, leftAreOdd, side);

		if (i & 0x1)
			delete q0;
	}

	return leftAreOdd;
}