// Construct a solid cylinder. Optional parameters are `start`, `end`, // `radius`, and `slices`, which default to `[0, -1, 0]`, `[0, 1, 0]`, `1`, and // `16`. The `slices` parameter controls the tessellation. // // Example usage: // // var cylinder = CSG.cylinder({ // start: [0, -1, 0], // end: [0, 1, 0], // radius: 1, // slices: 16 // }); static public CSG cylinder(CSGVector3 s, CSGVector3 e, float radius, int slices, CSGShared shared) { CSGVector3 ray = e.minus(s); CSGVector3 axisZ = ray.unit(); bool isY = (Math.Abs(axisZ.y) > 0.5f); CSGVector3 axisX = new CSGVector3(isY ? 1 : 0, !isY ? 1 : 0, 0).cross(axisZ).unit(); CSGVector3 axisY = axisX.cross(axisZ).unit(); CSGVertex start = new CSGVertex(s, axisZ.negated()); CSGVertex end = new CSGVertex(e, axisZ.unit()); List <CSGPolygon> polygons = new List <CSGPolygon>(); for (float i = 0; i < slices; i++) { float t0 = i / slices; float t1 = (i + 1) / slices; //cylinderPoint(s, ray, radius, axisX, axisY, axisZ, polygons.Add( new CSGPolygon( new CSGVertex[] { start, cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t0, -1), cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t1, -1) }, shared)); polygons.Add( new CSGPolygon( new CSGVertex[] { cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t1, 0), cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t0, 0), cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t0, 0), cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t1, 0) }, shared)); polygons.Add( new CSGPolygon( new CSGVertex[] { end, cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t1, 1), cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t0, 1) }, shared)); } return(CSG.fromPolygons(polygons)); }
public void flip() { normal = normal.negated(); w = -w; }