/** * Makes a rectangle that is subdivided * * @param subdivisioins - the number of subdivisions * @param p1 - the first vertex * @param p2 - the second vertex * @param p3 - the third vertex * @param p4 - the fourth vertex */ void makeRectangle(int subdivisions, Vertex p1, Vertex p2, Vertex p3, Vertex p4){ float frac = 1.0/subdivisions; for(int j = 0; j < subdivisions; j++){ Vertex tl = p1*(1-j*frac) + p3*(j*frac); Vertex tr = p2*(1-j*frac) + p4*(j*frac); Vertex bl = p1*(1-(j+1)*frac) + p3*((j+1)*frac); Vertex br = p2*(1-(j+1)*frac) + p4*((j+1)*frac); makeTriangle(tl, bl, br); makeTriangle(tl, br, tr); } }
void testPolyhOut() { struct polyhedron *ph; AllocVar(ph); ph->id = nextId(); ph->names[0] = cloneString("Jim"); ph->names[1] = cloneString("Kent"); ph->polygonCount = 2; slAddTail(&ph->polygons, makeTriangle(0, 0, 0)); slAddTail(&ph->polygons, makeTriangle(0, 0, 100)); findBox(ph); polyhedronCommaOut(ph, stdout); printf("\n"); polyhedronFree(&ph); }
/** * makeSphere - Create sphere of a given radius, centered at the origin, * using spherical coordinates with separate number of thetha and * phi subdivisions. * * @param radius - Radius of the sphere * @param slides - number of subdivisions in the theta direction * @param stacks - Number of subdivisions in the phi direction. * * Can only use calls to addTriangle */ void makeSphere (float r, int slices, int stacks) { float cosp, cosp1, sinp, sinp1, sint, sint1, cost, cost1; for(int i = 0; i < slices; i++){ cosp = cos(i*M_PI/slices); cosp1 = cos((i+1)*M_PI/slices); sinp = sin(i*M_PI/slices); sinp1 = sin((i+1)*M_PI/slices); for(int j = 0; j < stacks; j++){ cost = cos(j*2*M_PI/stacks); cost1 = cos((j+1)*2*M_PI/stacks); sint = sin(j*2*M_PI/stacks); sint1 = sin((j+1)*2*M_PI/stacks); Vertex v1(r*cost*sinp, r*sint*sinp, r*cosp); Vertex v2(r*cost1*sinp, r*sint1*sinp, r*cosp); Vertex v3(r*cost*sinp1, r*sint*sinp1, r*cosp1); Vertex v4(r*cost1*sinp1, r*sint1*sinp1, r*cosp1); makeTriangle(v1, v3, v4); makeTriangle(v1,v2,v4); } } }
/** * Recursively subdivides a triangle * * @param subdivisions - the number of subdivisions * @param p1 - the first vertex * @param p2 - the second vertex * @param p3 - the third vertex * @param radius - the radius of the sphere */ void makeTriangleRecursive(int subdivisions, Vertex p1, Vertex p2, Vertex p3, float radius){ if(subdivisions == 1){ makeTriangle(p1*(radius/p1.magnitude()), p2*(radius/p2.magnitude()), p3*(radius/p3.magnitude())); return; } Vertex m1 = p1*0.5 + p2*0.5; Vertex m2 = p2*0.5 + p3*0.5; Vertex m3 = p3*0.5 + p1*0.5; makeTriangleRecursive(subdivisions-1, m1, m2, m3, radius); makeTriangleRecursive(subdivisions-1, m1, p1, m3, radius); makeTriangleRecursive(subdivisions-1, m1, m2, p2, radius); makeTriangleRecursive(subdivisions-1, p3, m2, m3, radius); }
inline void addVertex(const Vertex& v) { vertices.push_back(v); makeTriangle(); bSphere.recalc(v); }
vpolygons lwPolygon::triangulate() { vpolygons triangles; BitArray active(vertices.size(), true); // vertex part of polygon ? long vertexCount = vertices.size(); long triangleCount = 0; long start = 0; long p1 = 0; long p2 = 1; long m1 = vertexCount - 1; long m2 = vertexCount - 2; bool lastPositive = false; for (;;) { if (p2 == m2) { triangles.push_back(makeTriangle(m1, p1, p2)); break; } const Point3 vp1 = *vertices[p1]->point; const Point3 vp2 = *vertices[p2]->point; const Point3 vm1 = *vertices[m1]->point; const Point3 vm2 = *vertices[m2]->point; bool positive = false; bool negative = false; Vector3 n1 = normal.crossProduct((vm1 - vp2).normalise()); if (n1.dotProduct(vp1 - vp2) > epsilon) { positive = true; Vector3 n2 = normal.crossProduct((vp1 - vm1).normalise()); Vector3 n3 = normal.crossProduct((vp2 - vp1).normalise()); for (long a = 0; a < vertexCount; a++) { if ((a != p1) && (a != p2) && (a != m1) && active.bitSet(a)) { const Point3 v = *vertices[a]->point; if (n1.dotProduct((v - vp2).normalise()) > -epsilon && n2.dotProduct((v - vm1).normalise()) > -epsilon && n3.dotProduct((v - vp1).normalise()) > -epsilon) { positive = false; break; } } } } n1 = normal.crossProduct((vm2 - vp1).normalise()); if (n1.dotProduct(vm1 - vp1) > epsilon) { negative = true; Vector3 n2 = normal.crossProduct((vm1 - vm2).normalise()); Vector3 n3 = normal.crossProduct((vp1 - vm1).normalise()); for (long a = 0; a < vertexCount; a++) { if ((a != m1) && (a != m2) && (a != p1) && active.bitSet(a)) { const Point3 v = *vertices[a]->point; if (n1.dotProduct((v - vp1).normalise()) > -epsilon && n2.dotProduct((v - vm2).normalise()) > -epsilon && n3.dotProduct((v - vm1).normalise()) > -epsilon) { negative = false; break; } } } } if ((positive) && (negative)) { float pd = (vp2 - vm1).normalise().dotProduct((vm2 - vm1).normalise()); float md = (vm2 - vp1).normalise().dotProduct((vp2 - vp1).normalise()); if (fabs(pd - md) < epsilon) { if (lastPositive) positive = false; else negative = false; } else { if (pd < md) negative = false; else positive = false; } } if (positive) { active.clearBit(p1); triangles.push_back(makeTriangle(m1, p1, p2)); p1 = active.getNextSet(p1); p2 = active.getNextSet(p2); lastPositive = true; start = -1; } else if (negative) { active.clearBit(m1); triangles.push_back(makeTriangle(m2, m1, p1)); m1 = active.getPreviousSet(m1); m2 = active.getPreviousSet(m2); lastPositive = false; start = -1; } else { if (start == -1) start = p2; else if (p2 == start) break; m2 = m1; m1 = p1; p1 = p2; p2 = active.getNextSet(p2); } } return triangles; }