예제 #1
0
파일: geom.c 프로젝트: vnaybhat/emulab
// Construct a line through two points.
void initGeomLine(geomPt pt1, geomPt pt2, geomLine self)
{
  geomVec perp;

  geomCopy(pt1, self->pt1);
  geomCopy(pt2, self->pt2);

  // (A,B) is the vector perpendicular to right side of line, (deltaY, -deltaX).
  perp[0] = pt2[1]-pt1[1];
  perp[1] = pt1[0]-pt2[0];
  vecNormalize(perp, perp);
  self->A = perp[0];
  self->B = perp[1];

  // C is the negative of the distance of the line from the origin.
  self->C = 0.0;                    // Small chicken-and-egg problem...
  self->C = -signedDist(self,pt1);
}
static Plane_3 centerizePlane(const Plane_3 &p, const Point_3 &C, double sign)
{
	Plane_3 pp(p.a(), p.b(), p.c(),	p.d() + p.a() * C.x() + p.b() * C.y()
			+ p.c() * C.z());

	double a = pp.a();
	double b = pp.b();
	double c = pp.c();
	double d = pp.d();
	if (sign * signedDist(pp, C) < 0.)
	{
		a = -a;
		b = -b;
		c = -c;
		d = -d;
	}

	pp = Plane_3(a, b, c, d);

	return pp;
}
/* FIXME: Copied from Polyhedron_io.cpp with slight modifications. */
static std::shared_ptr<Polyhedron> convertWithAssociation(Polyhedron_3 p,
		const Point_3 &C, const std::vector<Plane_3> &initPlanes)
{
	/* Check for non-emptiness. */
	ASSERT(p.size_of_vertices());
	ASSERT(p.size_of_facets());

	int numVertices = p.size_of_vertices();
	int numFacets = p.size_of_facets();

	/* Allocate memory for arrays. */
	Vector3d *vertices = new Vector3d[numVertices];
	Facet *facets = new Facet[numFacets];

	/* Transform vertexes. */
	int iVertex = 0;
	for (auto vertex = p.vertices_begin(); vertex != p.vertices_end(); ++vertex)
	{
		Point_3 point = C + vertex->point();
		vertices[iVertex++] = Vector3d(point.x(), point.y(), point.z());
	}

	/*
	 * Transform facets.
	 * This algorithm is based on example kindly provided at CGAL online user
	 * manual. See example Polyhedron/polyhedron_prog_off.cpp
	 */
	int iFacet = 0;
	auto plane = p.planes_begin();
	auto facet = p.facets_begin();
	/* Iterate through the std::lists of planes and facets. */
	do
	{
		int id = p.indexPlanes_[iFacet];

		facets[id].id = id;

		/* Transform current plane. */
		Plane_3 pi = centerizePlane(*plane,
				Point_3(-C.x(), -C.y(), -C.z()),
				signedDist(initPlanes[id], C));
		facets[id].plane = Plane(Vector3d(pi.a(), pi.b(), pi.c()),
				pi.d());

		/*
		 * Iterate through the std::list of halfedges incident to the curent CGAL
		 * facet.
		 */
		auto halfedge = facet->facet_begin();

		/* Facets in polyhedral surfaces are at least triangles. 	*/
		CGAL_assertion(CGAL::circulator_size(halfedge) >= 3);

		facets[id].numVertices = CGAL::circulator_size(halfedge);
		facets[id].indVertices =
			new int[3 * facets[id].numVertices + 1];
		/*
		 * TODO: It's too unsafe architecture if we do such things as setting
		 * the size of internal array outside the API functions. Moreover, it
		 * can cause us to write memory leaks.
		 * indFacets and numFacets should no be public members.
		 */

		int iFacetVertex = 0;
		do
		{
			facets[id].indVertices[iFacetVertex++] =
				std::distance(p.vertices_begin(), halfedge->vertex());
		} while (++halfedge != facet->facet_begin());

		/* Add cycling vertex to avoid assertion during printing. */
		facets[id].indVertices[facets[id].numVertices] =
			facets[id].indVertices[0];

		ASSERT(facets[id].correctPlane());

		/* Increment the ID of facet. */
		++iFacet;

	} while (++plane != p.planes_end() && ++facet != p.facets_end());

	return std::make_shared<Polyhedron>(numVertices, numFacets, vertices,
			facets);
}