// GeometryFactory // Dave Bollinger // http://www.davebollinger.com // // for generating a few primitives not currently built-in to p5 // syntax as of Processing 0123 Beta // note: -y is arbitrarily "up" for purposes of positive height "h" values // so, to get a +y tip on a cone, for example, pass a negative height class GeometryFactory { private static final int DEFAULT_DETAIL = 12; private int detail; private float [] costab, sintab; /** * Constructor * No parameters. */ GeometryFactory() { setDetail(DEFAULT_DETAIL); } /** * Constructor * with specified detail level "d" */ GeometryFactory(int d) { setDetail(d); } /** * Sets the resolution of internal trig tables used to construct geometry * (the assumption is that under normal usage this isn't called that frequently, * so the allocations and calculations are ok, this way we have an idealized * set of lookup values for the specific detail level we're working at. otoh, * if you'll be changing detail level frequently then this approach ain't for you!) */ public void setDetail(int d) { detail = (d < 3) ? 3 : d; // tables are built one too large to simplify looping elsewhere costab = new float[detail+1]; sintab = new float[detail+1]; float span = TWO_PI / (float)(detail); for (int i=0; i<=detail; i++) { costab[i] = cos((float)(i) * span); sintab[i] = sin((float)(i) * span); } } /** * simple accessor for current detail level */ public int getDetail() { return detail; } /** * private vertex helper function * issues a vertex from the trig tables * at specified angle t, radius r and y */ private void tvertex(int t, float r, float y) { vertex(r*costab[t], y, r*sintab[t]); } /** * disc() * creates a flat disc in the x-z plane * at specified y * of specified radius r */ public void disc(float y, float r) { beginShape(TRIANGLE_FAN); vertex(0f,y,0f); for (int i=0; i<=detail; i++) vertex(r*costab[i], y, r*sintab[i]); endShape(); } /** * cone() * creates a cone with it's base on the x-z plane * of specified radius r * at specified height h along the negative y axis */ public void cone(float h, float r) { beginShape(TRIANGLE_FAN); vertex(0f,-h,0f); for (int i=0; i<=detail; i++) vertex(r*costab[i], 0f, r*sintab[i]); endShape(); } /** * capped_cone() * creates a capped cone with it's base on the x-z plane * of specified radius r * at specified height h along the negative y axis */ public void capped_cone(float h, float r) { cone(h,r); disc(0,r); } /** * cylinder() * creates a cylinder with it's base on the x-z plane * of specified radius r * at specified height h along the negative y axis */ public void cylinder(float h, float r) { beginShape(TRIANGLE_STRIP); for (int i=0; i<=detail; i++) { float rcosi = r * costab[i]; float rsini = r * sintab[i]; vertex(rcosi, 0f, rsini); vertex(rcosi, h, rsini); } endShape(); } /** * capped_cylinder() * creates a capped cylinder with it's base on the x-z plane * of specified radius r * at specified height h along the negative y axis */ public void capped_cylinder(float h, float r) { cylinder(h,r); disc(0,r); disc(h,r); } /** * cylinder() * creates a "cylinder" with it's base on the x-z plane * of specified base radius r1 * of specified top radius r2 * at specified height h along the negative y axis */ public void cylinder(float h, float r1, float r2) { beginShape(TRIANGLE_STRIP); for (int i=0; i<=detail; i++) { vertex(r1 * costab[i], 0f, r1 * sintab[i]); vertex(r2 * costab[i], h, r2 * sintab[i]); } endShape(); } /** * capped_cylinder() * creates a capped "cylinder" with it's base on the x-z plane * of specified base radius r1 * of specified top radius r2 * at specified height h along the negative y axis */ public void capped_cylinder(float h, float r1, float r2) { cylinder(h,r1,r2); disc(0,r1); disc(h,r2); } }