/// <summary> /// Calculates a mesh for an RLD surface. /// </summary> private static Mesh SurfaceInternal(out RLD_outputs outputs) { Mesh mesh = new Mesh(); Func <double, double, double, Vector3D[]> oneCircle = (x, o, scale) => { Vector3D normal = Normal(x, o * scale); Vector3D cen = new Vector3D(0, 0, normal.Z); Vector3D radius = new Vector3D(normal.X, 0); return(Shapeways.Disk(cen, new Vector3D(0, 0, 1), radius, m_params.Res)); }; outputs = RLD_Sphere(m_params.K); double s = m_params.Scale; //double s = outputs.scale; // Add in two bands for each segment along the profile, one for +z coords, and one for -z coords. Vector3D[] profile = outputs.profile; for (int i = 0; i < profile.Length - 1; i++) { Vector3D p1 = profile[i]; Vector3D p2 = profile[i + 1]; mesh.AddBand(oneCircle(p1.X, p1.Y, s), oneCircle(p2.X, p2.Y, s)); mesh.AddBand(oneCircle(p1.X, -p1.Y, s), oneCircle(p2.X, -p2.Y, s)); } return(mesh); }
/// <summary> /// Calculates a mesh for a standard euclidean catenoid. /// This will need to be transformed to the various locations later. /// </summary> private static Mesh StandardCatenoid(double waist, double height) { Mesh mesh = new Mesh(); int res = m_params.Res * 2; Func <double, Vector3D[]> oneCircle = z => { double r = waist * Math.Cosh(z / waist); Vector3D cen = new Vector3D(0, 0, z); Vector3D radius = new Vector3D(r, 0); return(Shapeways.Disk(cen, new Vector3D(0, 0, 1), radius, res)); }; double inc = height / (res * 2); for (int i = 0; i < res; i++) { double z1 = inc * i; double z2 = inc * (i + 1); mesh.AddBand(oneCircle(z1), oneCircle(z2)); mesh.AddBand(oneCircle(-z1), oneCircle(-z2)); } return(mesh); }
private static Mesh ThickenBoundary(Vector3D[] edge, System.Func <Vector3D, System.Tuple <Vector3D, Vector3D> > thickenFn) { List <Vector3D> side1 = new List <Vector3D>(); List <Vector3D> side2 = new List <Vector3D>(); foreach (Vector3D v in edge) { var thickened = thickenFn(v); side1.Add(thickened.Item1); side2.Add(thickened.Item2); } Mesh m = new Mesh(); m.AddBand(side1.ToArray(), side2.ToArray(), close: false); return(m); }
private static void ThinMesh(H3.Cell.Edge[] edges, System.Func <H3.Cell.Edge, Vector3D[]> divider, out Mesh thinMesh, out List <Vector3D[]> boundaryPoints) { thinMesh = new Mesh(); boundaryPoints = new List <Vector3D[]>(); List <Vector3D> starts = new List <Vector3D>(); List <Vector3D> ends = new List <Vector3D>(); for (int i = 0; i < edges.Length - 1; i++) { int idx1 = i; int idx2 = i + 1; H3.Cell.Edge e1 = edges[idx1]; H3.Cell.Edge e2 = edges[idx2]; Vector3D[] points1 = divider(e1); Vector3D[] points2 = divider(e2); thinMesh.AddBand(points1, points2, close: false); starts.Add(e1.Start); ends.Add(e1.End); if (idx1 == 0) { boundaryPoints.Add(points1); } if (idx2 == edges.Length - 1) { boundaryPoints.Add(points2); starts.Add(e2.Start); ends.Add(e2.End); } } starts.Reverse(); boundaryPoints.Add(starts.ToArray()); boundaryPoints.Add(ends.ToArray()); }
/// <summary> /// Calculates a mesh for a standard euclidean catenoid. /// This will need to be transformed to the various locations later. /// /// Like above, but we adjust the xy components of the mesh using one of the mappings described here: /// https://arxiv.org/ftp/arxiv/papers/1509/1509.06344.pdf /// I found that paper here: /// https://stackoverflow.com/questions/13211595/how-can-i-convert-coordinates-on-a-circle-to-coordinates-on-a-square /// This is so we can connect up to the RLD mesh later. /// </summary> private static Mesh CatenoidSquared(double waist, double height) { Mesh mesh = new Mesh(); int res = m_params.Res * 2; double diskRad = waist * Math.Cosh(height / 2 / waist);; // NOTE: A band is *not* a constant height slice, // so the input z value is the height at the edge midpoints of the square. Func <double, Vector3D[]> oneCircle = z => { bool neg = z < 0; z = Math.Abs(z); // Radius on disk at a starting edge midpoint. double r = waist * Math.Cosh(z / waist); Vector3D start = new Vector3D(r, 0); Vector3D axis = new Vector3D(0, 0, 1); List <Vector3D> points = new List <Vector3D>(); double angleInc = 2 * Math.PI / res; double angle = 0; for (int i = 0; i < res; i++) { Vector3D point = start; point.RotateAboutAxis(axis, angle); point = DiskToSquare(point, diskRad); double zi = waist * DonHatch.acosh(point.Abs() / waist); if (double.IsNaN(zi)) { zi = 0; } if (neg) { zi *= -1; } Vector3D newPoint = new Vector3D(point.X, point.Y, zi); if (newPoint.DNE) { throw new System.Exception(); } points.Add(newPoint); angle += angleInc; } return(points.ToArray()); }; double inc = height / (res * 2); for (int i = 0; i < res; i++) { double z1 = inc * i; double z2 = inc * (i + 1); mesh.AddBand(oneCircle(z1), oneCircle(z2)); mesh.AddBand(oneCircle(-z1), oneCircle(-z2)); } return(mesh); }