/// <summary> /// Create a sphere (or one of it's domes) at 'position' with radius specified /// </summary> /// <param name="position"></param> /// <param name="radius"></param> /// <param name="steps"></param> /// <param name="domes"></param> public Sphere(Point3F position, double radius, int steps = 45, Domes domes = Domes.Both) : this(radius, steps, domes) { Transform.Translate(position); ApplyTransformation(); Transform = Matrix4x4F.Identity; }
private void BuildDomes(double radius, int steps, Domes domes) { Polyline curve = new Circle(0, 0, radius).ToPolyline(); // we need steps to be dividable by 4 !! steps = ((steps / 4) + ((steps % 4) != 0 ? 4 : 0)) * 4; // the circle acts as our equator being positioned at 0,0,0 List <Point3F> equator = new List <Point3F>(steps + 1); // fill the equator for (double i = 0; i <= 1; i = i + 1 / (double)steps) { equator.Add(curve.GetParametricPoint(i)); } // close the point count equator.Add(curve.GetParametricPoint(0)); int equ = equator.Count; int num = 0; // here our top dome will have it's points LinkedList <Point3F> spherePointsTop = new LinkedList <Point3F>(); double height = 0; double factor = 1; // Domes.Top starts at the first increment if (domes == Domes.Top) { // insert the equator foreach (Point3F p in equator) { spherePointsTop.AddFirst(p); } num++; } if (domes == Domes.Both || domes == Domes.Top) { // build the top dome for (int stp = 0; stp != (steps / 4); stp++) { // use the equator's points to build the height rings height = (equator[stp < (equ - 1) ? stp + 1 : 0].Y); factor = (equator[stp < (equ - 1) ? stp + 1 : 0].X) / radius; for (int cnt = 0; cnt != equ; cnt++) { Point3F item = equator[cnt]; item.X *= factor; item.Y *= factor; item.Z = height; spherePointsTop.AddFirst(item); } num++; } } // here our bottom dome will have it's points LinkedList <Point3F> spherePointsBottom = new LinkedList <Point3F>(); if (domes == Domes.Both || domes == Domes.Bottom) { // build the bottom dome for (int stp = ((steps / 2) + (steps / 4)) - 1; stp != steps; stp++) { // use the equator's points to build the height rings height = (equator[stp < (equ - 1) ? stp + 1 : 0].Y); factor = (equator[stp < (equ - 1) ? stp + 1 : 0].X) / radius; for (int cnt = 0; cnt != equ; cnt++) { Point3F item = equator[cnt]; item.X *= factor; item.Y *= factor; item.Z = height; spherePointsBottom.AddFirst(item); } num++; } } // combine top and bottom dome into our points list Points.AddRange(spherePointsTop.ToArray()); Points.AddRange(spherePointsBottom.ToArray()); // build triange list List <TriangleFace> faces = new List <TriangleFace>(Points.Count * 2); for (int stp = 0; stp != (num - 1); stp++) { for (int k = 0; k < (equ - 1); k++) { int idxp = (stp * equ) + k; faces.Add(new TriangleFace(idxp, idxp + 1, idxp + equ + 1)); faces.Add(new TriangleFace(idxp, idxp + equ + 1, idxp + equ)); } } Faces = faces.ToArray(); }
/// <summary> /// Create a sphere (or one of it's domes) at 0,0,0 with radius specified /// </summary> /// <param name="radius"></param> /// <param name="steps"></param> /// <param name="domes"></param> public Sphere(double radius, int steps = 45, Domes domes = Domes.Both) : this() { BuildDomes(radius, steps, domes); }