public static Solid Union(Solid head, Solid rest) { return(head.Union(rest)); }
public static Solid Sphere(SphereOptions options) { var center = options.Center; float radius = Math.Abs(options.Radius); if (radius == 0.0) { return(new Solid()); } var resolution = options.Resolution; var xvector = options.XAxis * radius; var yvector = options.YAxis * radius; var zvector = options.ZAxis * radius; if (resolution < 4) { resolution = 4; } var qresolution = resolution / 4; var prevcylinderpoint = new Vector3(0, 0, 0); var polygons = new List <Polygon>(); for (var slice1 = 0; slice1 <= resolution; slice1++) { float angle = (float)Math.PI * 2.0f * slice1 / resolution; Vector3 cylinderpoint = xvector * ((float)Math.Cos(angle)) + (yvector * ((float)Math.Sin(angle))); if (slice1 > 0) { float prevcospitch = 0, prevsinpitch = 0; for (var slice2 = 0; slice2 <= qresolution; slice2++) { float pitch = 0.5f * (float)Math.PI * slice2 / qresolution; float cospitch = (float)Math.Cos(pitch); float sinpitch = (float)Math.Sin(pitch); if (slice2 > 0) { List <Vertex> vertices = new List <Vertex>(); vertices.Add(NoTexVertex(center + (prevcylinderpoint * (prevcospitch) - (zvector * (prevsinpitch))))); vertices.Add(NoTexVertex(center + (cylinderpoint * (prevcospitch) - (zvector * (prevsinpitch))))); if (slice2 < qresolution) { vertices.Add(NoTexVertex(center + (cylinderpoint * (cospitch) - (zvector * (sinpitch))))); } vertices.Add(NoTexVertex(center + (prevcylinderpoint * (cospitch) - (zvector * (sinpitch))))); polygons.Add(new Polygon(options.SolidColor, vertices.ToArray())); vertices = new List <Vertex>(); vertices.Add(NoTexVertex(center + (prevcylinderpoint * (prevcospitch) + (zvector * (prevsinpitch))))); vertices.Add(NoTexVertex(center + (cylinderpoint * (prevcospitch) + (zvector * (prevsinpitch))))); if (slice2 < qresolution) { vertices.Add(NoTexVertex(center + (cylinderpoint * (cospitch) + (zvector * (sinpitch))))); } vertices.Add(NoTexVertex(center + (prevcylinderpoint * (cospitch) + (zvector * (sinpitch))))); vertices.Reverse(); polygons.Add(new Polygon(options.SolidColor, vertices.ToArray())); } prevcospitch = cospitch; prevsinpitch = sinpitch; } } prevcylinderpoint = cylinderpoint; } var result = Solid.FromPolygons(polygons); return(result); }
public static Solid Cylinder(CylinderOptions options) { var s = options.Start; var e = options.End; var r = Math.Abs(options.RadiusStart); var rEnd = Math.Abs(options.RadiusEnd); var rStart = r; var alpha = options.SectorAngle; alpha = alpha > 360 ? alpha % 360 : alpha; if ((rEnd == 0) && (rStart == 0)) { return(new Solid()); } if (s.Equals(e)) { return(new Solid()); } var slices = options.Resolution; var ray = e - (s); Vector3 axisZ = ray.Unit(); Vector3 axisX = axisZ.RandomNonParallelVector().Unit(); Vector3 axisY = axisX.Cross(axisZ).Unit(); axisX = axisZ.Cross(axisY).Unit(); var start = NoTexVertex(s); var end = NoTexVertex(e); var polygons = new List <Polygon>(); Func <float, float, float, Vertex> point = (stack, slice, radius) => { var angle = slice * Math.PI * alpha / 180; Vector3 outp = axisX * ((float)Math.Cos(angle)) + (axisY * ((float)Math.Sin(angle))); var pos = s + (ray * (stack)) + (outp * (radius)); return(NoTexVertex(pos)); }; if (alpha > 0) { for (var i = 0; i < slices; i++) { float t0 = (float)i / slices; float t1 = (float)(i + 1) / slices; if (rEnd == rStart) { polygons.Add(new Polygon(options.SolidColor, start, point(0, t0, rEnd), point(0, t1, rEnd))); polygons.Add(new Polygon(options.SolidColor, point(0, t1, rEnd), point(0, t0, rEnd), point(1, t0, rEnd), point(1, t1, rEnd))); polygons.Add(new Polygon(options.SolidColor, end, point(1, t1, rEnd), point(1, t0, rEnd))); } else { if (rStart > 0) { polygons.Add(new Polygon(options.SolidColor, start, point(0, t0, rStart), point(0, t1, rStart))); polygons.Add(new Polygon(options.SolidColor, point(0, t0, rStart), point(1, t0, rEnd), point(0, t1, rStart))); } if (rEnd > 0) { polygons.Add(new Polygon(options.SolidColor, end, point(1, t1, rEnd), point(1, t0, rEnd))); polygons.Add(new Polygon(options.SolidColor, point(1, t0, rEnd), point(1, t1, rEnd), point(0, t1, rStart))); } } } if (alpha < 360) { polygons.Add(new Polygon(options.SolidColor, start, end, point(0, 0, rStart))); polygons.Add(new Polygon(options.SolidColor, point(0, 0, rStart), end, point(1, 0, rEnd))); polygons.Add(new Polygon(options.SolidColor, start, point(0, 1, rStart), end)); polygons.Add(new Polygon(options.SolidColor, point(0, 1, rStart), point(1, 1, rEnd), end)); } } var result = Solid.FromPolygons(polygons); return(result); }