void stellate (Scene &body, float height) // // Adds starlike jags to every facet of the body. The tip // of a jag is placed in the given height over the center // of the facet. // { float nx,ny,nz,nk,nn,cx,cy,cz,h; Vertex* tip; Facet* f; int i,j,n; Scene stella; for (f = body.TheFacets(); f; f = f->NextFacet() ) { // calculate the normal form and the center of the facet f->Normal(nx,ny,nz,nk); f->Center(cx,cy,cz); // normalization of the normal vector to unit length nn = hypot(nx,ny,nz); // check if facet is degenerate if (nn == 0) continue; // add the tip vertex of the jag h = height / nn; tip = &stella.AddVertex( cx+h*nx, cy+h*ny, cz+h*nz ); // add three-sided facets for each side of the jag n = f->GetNumVertices(); for (i = 0, j = n-1; i < n; j = i++) { Facet& s = stella.AddFacet(3); s(0) = &stella.AddVertex( *(*f)(j) ); s(1) = &stella.AddVertex( *(*f)(i) ); s(2) = tip; } } // now clear the original body.Remove(); // and add the stellated body instead (duplicate vertices are now removed) body.AddScene(stella,Identity); }
void Scene::FlatFacet (Facet& f) // // If shading is 'Flat' the facet is drawn using flat shading, otherwise // if shading is 'false' it will be filled with the background color. // // Uses the global intermediate storage array pix. // { int i,j; float cx,cy,cz,nx,ny,nz,nk; short r,g,b; long color; // number of vertices int n = f.GetNumVertices(); // facet is degenerate (a line) ----- CURRENTLY DEGENERATE NOT ALLOWED if (n == 2) { Line(f[0].p,f[1].p); return; } // can't happen ! if (n < 2 || n > MaxVertices) { Warn("Scene::FlatFacet: number of vertices out of range"); return; } static Material M; Material *Mp; if (coloring == Global) { Mp = f.GetMaterial(); } else { M.color = f.front; if (f.material) { M.ambient = f.material->ambient; M.specular = f.material->specular; M.exponent = f.material->exponent; } else { M.ambient = mat.ambient; M.specular = mat.specular; M.exponent = mat.exponent; } Mp = &M; } // copy projected vertex coordinates to polygon array for (i = 0; i < n; i++) pix[i] = f[i].p; // compute color of facet from reflection properties if (shading == Facet::Flat) { f.Normal(nx,ny,nz,nk); f.Center(cx,cy,cz); PhongColor(cx,cy,cz,nx,ny,nz,Mp,r,g,b); // find color in colormap //color = LookupColor(r,g,b,f.GetMaterial()); color = LookupColor(r,g,b,&mat); // else if (shading == false) then use the background color } else color = backcolor; // ======================================================= // testing: fog for edgelines to get a depth cueing effect // ======================================================= ColorF previous_color; if (fog_opacity) { previous_color = foreground_color; SetColor( ColorF_Weighted(0.5*(1-tanh((6/fog_opacity) *(hypot(cx,cy,cz)-fog_distance-1))), previous_color,fog_color) ); } // draw outlines if requested if (edgelines == 1) Polygon(n,pix,color,Outline|Fill); else if (edgelines == 0) Polygon(n,pix,color,Fill); else if (edgelines == Facet::Individual ) { if (f.edgelines == 1) Polygon(n,pix,color,Outline|Fill); else if (f.edgelines == 0) Polygon(n,pix,color,Fill); else if (f.edgelines == Facet::Individual) { Polygon(n,pix,color,Fill); for (i = 0, j = n-1; i < n; j = i++) if ( f.GetEdgeLine(j) ) Line(pix[j],pix[i]); } } if (fog_opacity) SetColor(previous_color); }