internal static CoxeterImages.Settings AutoCalcScale(HoneycombDef def, Sphere[] mirrors) { // Calculate the color scale. int size = 200; CoxeterImages.Settings settings = new CoxeterImages.Settings() { Honeycomb = def, Width = size, Height = size, Bounds = 1.1, Mirrors = mirrors, FileName = def.FormatFilename(), }; CoxeterImages imageCalculator = new CoxeterImages(); imageCalculator.AutoCalcScale(settings); if (settings.ColorScaling < 1) { settings.ColorScaling = 15; } return(settings); }
public static void DoStuff(Settings settings) { HoneycombDef imageData = new HoneycombDef(settings.P, settings.Q, settings.R); ////////////////////////////////////////////////////////////// Various things we've run over time. //Sandbox.CalcSelfSimilarityScale(); //Sandbox.Check_pq_Distances(); //HyperidealSquares(); //S3.Hypercube(); //R3.Geometry.Euclidean.GenEuclidean(); //HoneycombGen.OneHoneycombOldCode(); //AnimateCell( imageData ); //CreateCellPovRay( imageData, "cell.pov" ); //CreateSimplex( imageData ); //HoneycombGen_old.OneHoneycombNew( new HoneycombDef() { P = imageData.P, Q = imageData.Q, R = imageData.R } ); //SphericalAnimate( imageData ); OneImage(settings); HoneycombDef[] scaleLarger = GetImageSet().Where(h => Geometry2D.GetGeometry(h.P, h.Q) == Geometry.Euclidean || Geometry2D.GetGeometry(h.P, h.Q) == Geometry.Spherical).ToArray(); int count = scaleLarger.Length; //foreach( HoneycombAndView h in scaleLarger ) // Trace.WriteLine( h.FormatFilename() ); //BatchRun( settings ); }
public void AnimationSections(Settings config) { HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R); int p = imageData.P, q = imageData.Q, r = imageData.R; string filename = imageData.FormatFilename(); Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r); double bounds = 1.0; //config.UhsBoundary.Bounds; bounds = 9.0; // Calculate the color scale. int size = 200; CoxeterImages.Settings settings = new CoxeterImages.Settings() { Honeycomb = imageData, Width = size, Height = size, Bounds = bounds, Mirrors = mirrors, FileName = imageData.FormatFilename(), }; CoxeterImages imageCalculator = new CoxeterImages(); //imageCalculator.AutoCalcScale( settings ); if (settings.ColorScaling < 1) { settings.ColorScaling = 15; } settings.ColorScaling = 11; Program.Log("\nGenerating sections..."); size = 500; settings.Width = size; settings.Height = size; settings.FileName = filename; double max = Spherical2D.e2sNorm(15); double min = Spherical2D.e2sNorm(1.0 / 15); DonHatch.e2hNorm(max); int numSteps = 1800; // 1 minute double step = (max - min) / numSteps; for (int i = 0; i < 1; i++) { Program.Log("\nSection " + i); imageCalculator.m_z = 1.0 / 0.5; Spherical2D.s2eNorm(min + step * i); DonHatch.h2eNorm(step * i); settings.FileName = string.Format("533_{0:D4}.png", i); imageCalculator.GenImage(settings); } }
/// <summary> /// The input time should lie in [0,1] /// </summary> /// <param name="t"></param> public static void ParacompactAnimationFrame(double t) { var def = new HoneycombDef(4, 4, 4); var active = new int[] { 1, 2 }; int baseHue = -1; // Black. //baseHue = 135; ViewPath.Time = t; OneHoneycombOrthoscheme(def, active, baseHue); }
public static void Create(HoneycombDef def, string filename) { int p = def.P; int q = def.Q; int r = def.R; double scale = 5.0; Vector3D cen = HoneycombPaper.InteriorPointBall; Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: false); // Apply transformations. simplex = simplex.Select(s => { Sphere.ScaleSphere(s, scale); return(H3Models.UHSToBall(s)); }).ToArray(); for (int i = 0; i < 4; i++) { if (simplex[i].IsPointInside(cen)) { simplex[i].Invert = true; } } Sphere[] simplexForColorScale = SimplexCalcs.Mirrors(p, q, r, moveToBall: true); CoxeterImages.Settings temp = HoneycombPaper.AutoCalcScale(def, simplexForColorScale); int maxDepth = (int)temp.ColorScaling; bool ball = true; bool dual = false; H3.Cell[] simplicesFinal = HoneycombPaper.GenCell(simplex, null, cen, ball, dual); simplicesFinal = simplicesFinal.Where(s => s.Depths[0] < 1).ToArray(); //simplicesFinal = simplicesFinal.Where( s => s.) // Output the facets. using (StreamWriter sw = File.CreateText(filename)) // We need to reuse this StreamWriter (vs. calling AppendSimplex) for performance. { sw.WriteLine("#include \"hyper_ball.pov\""); int[] include = new int[] { 0 }; foreach (H3.Cell cell in simplicesFinal) { Sphere[] facets = cell.Facets.Select(f => f.Sphere).ToArray(); int depth = cell.Depths[0] + 1; Color c = Coloring.ColorAlongHexagon(maxDepth, depth); PovRay.AddSimplex(sw, facets, cell.Center, include, filename, Coloring.ToVec(c)); } } }
private static void SphericalAnimate(HoneycombDef imageData) { double colorScaling = AnimColorScaling(imageData); //int fps = 30; //int frames = 60 * fps; int frames = 5; for (int i = 0; i < frames; i++) { double t = (double)i / frames; string filename = "batch/" + imageData.FormatFilename(string.Empty) + FrameString(i) + ".png"; OneAnimationFrame(imageData, filename, colorScaling, t); } }
private static void AnimateCell(HoneycombDef imageData) { int numFrames = 100; for (int i = 0; i < numFrames; i++) { double t = (double)i / numFrames; string filename = "batch/cell" + FrameString(i) + ".pov"; Console.WriteLine(filename); System.IO.File.Delete(filename); using (StreamWriter sw = new StreamWriter(filename)) sw.WriteLine("#include \"C:\\Users\\hrn\\Documents\\roice\\povray\\H3\\horosphere\\633.pov\""); CreateCellPovRay(imageData, filename, t); } }
public static void OneImage(Settings config, double t = 0.0) { HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R); int p = imageData.P, q = imageData.Q, r = imageData.R; string filename = imageData.FormatFilename(); //if( File.Exists( filename ) ) // return; Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r); double bounds = config.UhsBoundary.Bounds; // Calculate the color scale. int size = 200; CoxeterImages.Settings settings = new CoxeterImages.Settings() { Honeycomb = imageData, Width = size, Height = size, Bounds = bounds, Mirrors = mirrors, FileName = imageData.FormatFilename(), }; CoxeterImages imageCalculator = new CoxeterImages(); imageCalculator.AutoCalcScale(settings); if (settings.ColorScaling < 1) { settings.ColorScaling = 15; } Program.Log("\nGenerating full image..."); size = 500; settings.Width = config.UhsBoundary.ImageWidth; settings.Height = config.UhsBoundary.ImageHeight; settings.FileName = filename; imageCalculator.GenImage(settings, t); }
private static void CreateSimplex(HoneycombDef imageData) { int p = imageData.P; int q = imageData.Q; int r = imageData.R; Vector3D cen = InteriorPointBall; bool ball = true; Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, ref cen, moveToBall: ball); // Offset as we do for the boundary images. //Sphere s = H3Models.UHSToBall( simplex[0] ); //s = CoxeterImages.GeodesicOffset( s, 0.02, ball: true ); if (m_toKlein) { simplex = simplex.Select(s => H3Models.BallToKlein(s)).ToArray(); } int[] include = new int[] { 0, 1, 2, 3 }; // All facets //int[] include = new int[] { 1 }; File.Delete("simplex.pov"); PovRay.AppendSimplex(simplex, cen, include, "simplex.pov"); bool includeEdges = false; if (includeEdges) { H3.Cell.Edge[] edges = SimplexCalcs.SimplexEdgesUHS(p, q, r); PovRay.WriteEdges(new PovRay.Parameters { Halfspace = true, AngularThickness = 0.03 }, Geometry.Hyperbolic, edges, "simplex.pov", append: true); } }
private static void OneAnimationFrame(HoneycombDef imageData, string filename, double colorScaling, double t = 0.0) { int p = imageData.P, q = imageData.Q, r = imageData.R; Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r); int size = 750; size = 1024; CoxeterImages.Settings settings = new CoxeterImages.Settings() { Honeycomb = imageData, Width = size * 2, Height = size, Bounds = 1.0, Mirrors = mirrors, FileName = filename, }; CoxeterImages imageCalculator = new CoxeterImages(); settings.ColorScaling = colorScaling; imageCalculator.GenImage(settings, t); }
// CHEAT! (would be better to do a geometrical construction) // We are going to iterate to the starting point that will make all edge lengths the same. public static Vector3D IterateToStartingPoint(HoneycombDef?def, int[] activeMirrors, Simplex simplex) { if (activeMirrors.Length == 1) { return(simplex.Verts[activeMirrors[0]]); } // We are minimizing the output of this function, // because we want all edge lengths to be as close as possible. // Input vector should be in the Ball Model. Func <Vector3D, double> diffFunc = v => { List <double> lengths = new List <double>(); for (int i = 0; i < activeMirrors.Length; i++) { Vector3D reflected = simplex.ReflectInFacet(v, activeMirrors[i]); lengths.Add(H3Models.Ball.HDist(v, reflected)); } double result = 0; double average = lengths.Average(); foreach (double length in lengths) { result += Math.Abs(length - average); } if (Infinity.IsInfinite(result)) { result = double.PositiveInfinity; } return(result); }; // So that we can leverage Euclidean barycentric coordinates, we will first convert our simplex to the Klein model. // We will need to take care to properly convert back to the Ball as needed. Vector3D[] kleinVerts = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray(); if (def != null) { HoneycombDef d = def.Value; Geometry vertexGeometry = Geometry2D.GetGeometry(d.Q, d.R); if (vertexGeometry == Geometry.Hyperbolic) { kleinVerts[3] = SimplexCalcs.VertexPointKlein(d.P, d.Q, d.R); } } // Normalizing barycentric coords amounts to making sure the 4 coords add to 1. Func <Vector3D, Vector3D> baryNormalize = b => { return(b / (b.X + b.Y + b.Z + b.W)); }; // Bary Coords to Euclidean Func <Vector3D[], Vector3D, Vector3D> baryToEuclidean = (kv, b) => { Vector3D result = kv[0] * b.X + kv[1] * b.Y + kv[2] * b.Z + kv[3] * b.W; return(result); }; // Our starting barycentric coords (halfway between all active mirrors). Vector3D bary = new Vector3D(); foreach (int a in activeMirrors) { bary[a] = 0.5; } bary = baryNormalize(bary); // For each iteration, we'll shrink this search offset. // NOTE: The starting offset and decrease factor I'm using don't guarantee convergence, // but it seems to be working pretty well (even when varying these parameters). //double searchOffset = 1.0 - bary[activeMirrors[0]]; //double searchOffset = bary[activeMirrors[0]]; double factor = 1.5; // Adjusting this helps get some to converge, e.g. 4353-1111 double searchOffset = bary[activeMirrors[0]] / factor; double min = double.MaxValue; int iterations = 1000; for (int i = 0; i < iterations; i++) { min = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, bary))); foreach (int a in activeMirrors) { Vector3D baryTest1 = bary, baryTest2 = bary; baryTest1[a] += searchOffset; baryTest2[a] -= searchOffset; baryTest1 = baryNormalize(baryTest1); baryTest2 = baryNormalize(baryTest2); double t1 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest1))); double t2 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest2))); if (t1 < min) { min = t1; bary = baryTest1; } if (t2 < min) { min = t2; bary = baryTest2; } } if (Tolerance.Equal(min, 0.0, 1e-14)) { System.Console.WriteLine(string.Format("Converged in {0} iterations.", i)); break; } searchOffset /= factor; } if (!Tolerance.Equal(min, 0.0, 1e-14)) { System.Console.WriteLine("Did not converge: " + min); // Be a little looser before thrown an exception. if (!Tolerance.Equal(min, 0.0, 1e-12)) { System.Console.ReadKey(true); //throw new System.Exception( "Boo. We did not converge." ); return(Vector3D.DneVector()); } } Vector3D euclidean = baryToEuclidean(kleinVerts, bary); return(HyperbolicModels.KleinToPoincare(euclidean)); }
public static H3.Cell.Edge[] OneHoneycombOrthoscheme(HoneycombDef def, int[] active, int baseHue, Settings settings = null) { // Setup parameters. int numEdges = 250000; if (settings != null) { active = settings.PovRay.Active; def = new HoneycombDef(settings.P, settings.Q, settings.R); numEdges = settings.PovRay.NumEdges; } CalcThickness(active); if (settings != null) { H3.m_settings.AngularThickness = settings.PovRay.EdgeWidth; // ZZZ - should really stop using that settings class. } string baseName = BaseName(def); string mirrorsString = ActiveMirrorsString(active); string suffix = "-" + mirrorsString; string fileName = baseName + suffix; if (ViewPath != null) { fileName += string.Format("_{0:D4}", ViewPath.Step); } if (File.Exists(fileName + ".pov")) { File.Delete(fileName + ".pov"); //Console.WriteLine( string.Format( "Skipping {0}", fileName ) ); //return; } Program.Log(string.Format("Building {0}", fileName)); // The wiki mirrors are labeled in the reverse of ours. Func <int, int> mapMirror = i => 3 - i; active = active.Select(i => mapMirror(i)).OrderBy(i => i).ToArray(); Simplex simplex = new Simplex(); simplex.Facets = SimplexCalcs.Mirrors(def.P, def.Q, def.R); simplex.Verts = SimplexCalcs.VertsBall(def.P, def.Q, def.R); Vector3D startingPoint = IterateToStartingPoint(def, active, simplex); if (startingPoint.DNE) { return(null); } List <H3.Cell.Edge> startingEdges = new List <H3.Cell.Edge>(); foreach (int a in active) { Vector3D reflected = simplex.ReflectInFacet(startingPoint, a); startingEdges.Add(new H3.Cell.Edge(startingPoint, reflected)); //startingEdges.Add( new H3.Cell.Edge( simplex.Verts[0], simplex.Verts[3] ) ); // Used for Borromean Rings complement image. } if (false) { Vector3D[] kv = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray(); kv[3] = SimplexCalcs.VertexPointKlein(def.P, def.Q, def.R); Vector3D t = (kv[3] - kv[0]) * 0.5; Sphere gSphere = H3Models.Ball.OrthogonalSphereInterior(HyperbolicModels.KleinToPoincare(t)); gSphere = H3Models.BallToKlein(gSphere); Vector3D t2 = Euclidean3D.IntersectionPlaneLine(gSphere.Normal, gSphere.Offset, kv[3] - kv[2], kv[2]); //t2 = kv[2] + ( kv[3] - kv[2]) * 0.5; t = HyperbolicModels.KleinToPoincare(t); t2 = HyperbolicModels.KleinToPoincare(t2); startingEdges.Add(new H3.Cell.Edge(t, t2)); startingEdges.Add(new H3.Cell.Edge(t, simplex.ReflectInFacet(t, 3))); } // If we are doing a view path, transform our geometry. if (ViewPath != null) { //Vector3D p = new Vector3D( 0, 0, .5 ); Vector3D p = new Vector3D(0.08, 0.12, 0.07); simplex.Facets = simplex.Facets.Select(f => H3Models.Transform_PointToOrigin(f, p)).ToArray(); simplex.Verts = simplex.Verts.Select(v => H3Models.Transform_PointToOrigin(v, p)).ToArray(); startingEdges = startingEdges.Select(e => new H3.Cell.Edge( H3Models.Transform_PointToOrigin(e.Start, p), H3Models.Transform_PointToOrigin(e.End, p))).ToList(); } SetupBaseHue(fileName, mirrorsString, baseHue); Recurse.m_background = baseHue == -1 ? new Vector3D() : new Vector3D(baseHue, 1, .1); H3.Cell.Edge[] edges = Recurse.CalcEdgesSmart2(simplex.Facets, startingEdges.ToArray(), numEdges); //H3.Cell.Edge[] edges = Recurse.CalcEdges( simplex.Facets, startingEdges.ToArray(), // new Recurse.Settings() { ThreshType = Recurse.EdgeThreshType.Radial, Threshold = H3Models.Ball.FindLocationForDesiredRadius( settings.PovRay.EdgeWidth, 0.8/100 ) } ); //edges = edges.Where( e => e.Depths[0] % 2 == 1 ).ToArray(); // Used for Borromean Rings complement image. // Shapeways truncated 436. if (false) { if (true) { Mobius m = Mobius.Scale(1.0 / H3Models.UHS.ToE(Honeycomb.InRadius(def.P, def.Q, def.R))); double a = -Math.PI / 2 + Math.Asin(1 / Math.Sqrt(3)); edges = edges.Select(e => { Vector3D v1 = e.Start; Vector3D v2 = e.End; v1.RotateAboutAxis(new Vector3D(1, 0, 0), a); v2.RotateAboutAxis(new Vector3D(1, 0, 0), a); v1 = H3Models.Ball.ApplyMobius(m, v1); v2 = H3Models.Ball.ApplyMobius(m, v2); return(new H3.Cell.Edge(v1, v2)); }).ToArray(); double thresh = -.01; Vector3D looking = new Vector3D(0, 0, -1); edges = edges.Where(e => e.Start.Dot(looking) > thresh && e.End.Dot(looking) > thresh).ToArray(); Dictionary <H3.Cell.Edge, int> edgeDict = edges.ToDictionary(e => e, e => 1); H3.RemoveDanglingEdgesRecursive(edgeDict); edges = edgeDict.Keys.ToArray(); } else { Mobius m = Mobius.Scale(2); edges = edges.Select(e => { Vector3D v1 = e.Start; Vector3D v2 = e.End; v1 = H3Models.Ball.ApplyMobius(m, v1); v2 = H3Models.Ball.ApplyMobius(m, v2); return(new H3.Cell.Edge(v1, v2)); }).ToArray(); Dictionary <H3.Cell.Edge, int> edgeDict = edges.ToDictionary(e => e, e => 1); H3.RemoveDanglingEdgesRecursive(edgeDict); edges = edgeDict.Keys.ToArray(); } } //H3.m_settings.Output = H3.Output.STL; //H3.m_settings.Scale = 50; H3.SaveToFile(fileName, edges, finite: true, append: true); bool doCells = false; H3.Cell[] cellsToHighlight = null; if (doCells) { int[] polyMirrors = new int[] { 1, 2, 3 }; active = active.Select(i => mapMirror(i)).OrderBy(i => i).ToArray(); H3.Cell startingCell = PolyhedronToHighlight(Geometry.Hyperbolic, polyMirrors, simplex, startingPoint); cellsToHighlight = Recurse.CalcCells(simplex.Facets, new H3.Cell[] { startingCell }); H3.AppendFacets(fileName, cellsToHighlight); } return(edges); }
private static string BaseName(HoneycombDef def) { return(string.Format("{0}-{1}-{2}", def.P, def.Q, def.R)); }
public static void ParacompactSet() { List <int[]> toRun = new List <int[]>(); toRun.Add(new int[] { 0, 1 }); toRun.Add(new int[] { 0, 2 }); toRun.Add(new int[] { 0, 3 }); toRun.Add(new int[] { 1, 2 }); toRun.Add(new int[] { 1, 3 }); toRun.Add(new int[] { 2, 3 }); toRun.Add(new int[] { 0, 1, 2 }); toRun.Add(new int[] { 0, 1, 3 }); toRun.Add(new int[] { 0, 2, 3 }); toRun.Add(new int[] { 1, 2, 3 }); toRun.Add(new int[] { 0, 1, 2, 3 }); //toRun.Clear(); //toRun.Add( new int[] { 0, 1, 3 } ); int baseHue = 0; HoneycombDef def; baseHue = 135; def = new HoneycombDef(6, 3, 3); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 220; def = new HoneycombDef(6, 3, 4); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 180; def = new HoneycombDef(6, 3, 5); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 255; def = new HoneycombDef(6, 3, 6); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 105; def = new HoneycombDef(3, 6, 3); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 300; def = new HoneycombDef(4, 4, 3); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } baseHue = 0; def = new HoneycombDef(4, 4, 4); foreach (int[] active in toRun) { OneHoneycombOrthoscheme(def, active, baseHue); } }
private static void HoneycombFiniteVertexFig(HoneycombDef def, int lod, Dictionary <Vector3D, H3.Cell> complete) { int p = def.P; int q = def.Q; int r = def.R; double scale = 1.0; Vector3D vUHS = H3Models.BallToUHS(SimplexCalcs.VertexPointBall(p, q, r)); if (Geometry2D.GetGeometry(q, r) != Geometry.Hyperbolic) // Vertex-centered if possible { scale = 1.0 / vUHS.Z; } System.Func <Vector3D, Vector3D> trans = v => { v = H3Models.BallToUHS(v); v *= scale; v = H3Models.UHSToBall(v); return(v); }; bool ball = true; Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: ball); simplex = simplex.Select(s => { s = H3Models.BallToUHS(s); Sphere.ScaleSphere(s, scale); s = H3Models.UHSToBall(s); return(s); }).ToArray(); H3.Cell.Edge[] edges = SimplexCalcs.SimplexEdgesBall(p, q, r); // Two edges of the simplex facet. // NOTE: This contruction only works for material triangles, and matches the construction in the TextureHelper. m_div = TextureHelper.SetLevels(lod); int[] elementIndices = TextureHelper.TextureElements(1, lod); List <Vector3D> points = new List <Vector3D>(); H3.Cell.Edge e1 = edges[2]; H3.Cell.Edge e2 = edges[3]; Vector3D p1 = trans(e1.Start), p2 = trans(e1.End), p3 = trans(e2.End); Vector3D[] points1 = H3Models.Ball.GeodesicPoints(p2, p1, m_div); Vector3D[] points2 = H3Models.Ball.GeodesicPoints(p3, p1, m_div); for (int i = 0; i < m_div; i++) { points.AddRange(H3Models.Ball.GeodesicPoints(points1[i], points2[i], m_div - i)); } points.Add(p1); Mesh mesh = new Mesh(); for (int i = 0; i < elementIndices.Length / 3; i++) { int idx1 = i * 3; int idx2 = i * 3 + 1; int idx3 = i * 3 + 2; Vector3D v1 = points[elementIndices[idx1]]; Vector3D v2 = points[elementIndices[idx2]]; Vector3D v3 = points[elementIndices[idx3]]; mesh.Triangles.Add(new Mesh.Triangle(v1, v2, v3)); } // AuxPoints will be used for multiple things. // - The first is a definition point for a face, so we can check for duplicates. // - We'll also store the points for the 3 edges of our fundamental triangle. List <Vector3D> auxPoints = new List <Vector3D>(); { auxPoints.Add((p1 + p2 + p3) / 3); auxPoints.AddRange(points1); auxPoints.AddRange(points2.Reverse()); auxPoints.AddRange(H3Models.Ball.GeodesicPoints(points2[0], points1[0], m_div)); } Vector3D cen = HoneycombPaper.InteriorPointBall; H3.Cell[] simplices = GenCell(simplex, mesh, cen, auxPoints.ToArray(), ball); // Existing cells take precedence. foreach (H3.Cell c in simplices) { Vector3D t = c.AuxPoints[0]; H3.Cell dummy; if (!complete.TryGetValue(t, out dummy)) { complete[t] = c; } } }
public static void Test() { HoneycombDef def = new HoneycombDef(5, 3, 4); Simplex simplex = new Simplex(); simplex.Facets = SimplexCalcs.Mirrors(def.P, def.Q, def.R); // Simplices will be the "cells" H3.Cell.Facet[] simplexFacets = simplex.Facets.Select(m => new H3.Cell.Facet(m)).ToArray(); H3.Cell startingCell = new H3.Cell(simplexFacets); startingCell.AuxPoints = SimplexCalcs.VertsBall(def.P, def.Q, def.R); startingCell.Center = HoneycombPaper.InteriorPointBall; var cells = CalcCells(simplex.Facets, new H3.Cell[] { startingCell }); // Get all the cell centers HashSet <Vector3D> centers = new HashSet <Vector3D>(); foreach (var cell in cells) { Vector3D cellCen = cell.AuxPoints[0]; centers.Add(cellCen); } // Colors. Dictionary <double, Color> colors = new Dictionary <double, Color>(new DoubleEqualityComparer()); System.Random rand = new System.Random(0); // Get all the in-spheres double inRad = startingCell.AuxPoints[1].Abs(); //inRad *= 1.16; List <Sphere> inSpheres = new List <Sphere>(); foreach (Vector3D c in centers) { Vector3D p = c; //SphericalModels.GnomonicToStereo( c ); Geometry g = Geometry.Hyperbolic; Vector3D cen; double rad; H3Models.Ball.DupinCyclideSphere(p, inRad, g, out cen, out rad); Sphere i = new Sphere(cen, rad); Color color; if (!colors.TryGetValue(c.Abs(), out color)) { Vector3D rgb = ColorUtil.CHSL2RGB(new Vector3D(rand.NextDouble() * 360, .5, .5)); rgb *= 255; color = Color.FromArgb(255, (int)rgb.X, (int)rgb.Y, (int)rgb.Z); colors[c.Abs()] = color; } i.Color = color; inSpheres.Add(i); } // Project sphere to unit sphere. List <Circle3D> circlesOnUnitSphere = new List <Circle3D>(); foreach (Sphere i in inSpheres) { if (i.Center.IsOrigin || i.Center.DNE || Infinity.IsInfinite(i.Center)) { continue; } Sphere orthogonal = new Sphere(new Vector3D(), RadiusOrthogonal(i)); Circle3D c = orthogonal.Intersection(i); // We need to scale this based on the size of the orthogonal sphere. c.Center /= orthogonal.Radius; c.Radius /= orthogonal.Radius; c.Color = i.Color; circlesOnUnitSphere.Add(c); } Circle3D unit = new Circle3D(); //circlesOnUnitSphere.Add( unit ); ProjectAndSave(circlesOnUnitSphere); }
public static void HoneycombHyperidealLegs(HoneycombDef def) { // This will be used to avoid duplicates. // The key is the cell center. Dictionary <Vector3D, H3.Cell> complete = new Dictionary <Vector3D, H3.Cell>(); m_thresh = 0.05; //m_thresh = 0.07; HoneycombHyperidealLegs(def, 3, complete); m_thresh = 0.01; //m_thresh = 0.02; HoneycombHyperidealLegs(def, 2, complete); m_thresh = 0.004; //m_thresh = 0.007; HoneycombHyperidealLegs(def, 1, complete); string filename = "cell.stl"; System.IO.File.Delete(filename); using (StreamWriter sw = File.AppendText(filename)) { HashSet <H3.Cell.Edge> edgesToMesh = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer()); foreach (H3.Cell cell in complete.Values) { int depth = cell.Depths.Sum(); Mesh m = new Mesh(); Sphere normal = cell.Facets[0].Sphere; foreach (Mesh.Triangle tri in cell.Mesh.Triangles) { Mesh.Triangle[] thickened = Thicken(tri, normal); m.Triangles.AddRange(thickened.Select(t => Transform(t))); } List <object> boundary = new List <object>(); int skip = 2; int stride = (int)Math.Sqrt(cell.Mesh.Triangles.Count) / 2 + 1; int num = stride; boundary.Add(cell.AuxPoints.Skip(skip).Take(num)); skip += num; boundary.Add(cell.AuxPoints.Skip(skip).Take(num)); skip += num; num = 2 * m_div + 1; boundary.Add(cell.AuxPoints.Skip(skip).Take(num)); skip += num; boundary.Add(cell.AuxPoints.Skip(skip).Take(num)); skip += num; foreach (object e in boundary) { var enumerable = (IEnumerable <Vector3D>)e; //if( depth % 2 == 0 ) // enumerable = enumerable.Reverse(); Mesh m2 = ThickenBoundary(enumerable.ToArray(), normal); if (depth % 2 == 0) { ReverseTris(m2); } m.Triangles.AddRange(m2.Triangles.Select(t => Transform(t))); } STL.AppendMeshToSTL(m, sw); edgesToMesh.Add(new H3.Cell.Edge(cell.AuxPoints[0], cell.AuxPoints[1])); } /*foreach( H3.Cell.Edge e in edgesToMesh ) * { * Mesh m3 = new Mesh(); * AddEdge( m3, Transform( e.Start ), Transform( e.End ) ); * STL.AppendMeshToSTL( m3, sw ); * }*/ } }
/// <summary> /// Create an STL file for a cell. /// Currently only works for cells with both hyperideal vertices and cells. /// </summary> public static void HoneycombHyperidealLegs(HoneycombDef def, int lod, Dictionary <Vector3D, H3.Cell> complete) { int p = def.P; int q = def.Q; int r = def.R; m_div = TextureHelper.SetLevels(lod); bool ball = false; Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: ball); H3.Cell.Edge[] edges; if (ball) { edges = SimplexCalcs.SimplexEdgesBall(p, q, r); } else { edges = SimplexCalcs.SimplexEdgesUHS(p, q, r); } // Two edges of one simplex facet. H3.Cell.Edge e1 = edges[2]; H3.Cell.Edge e2 = edges[3]; Vector3D[] points1, points2; if (ball) { points1 = H3Models.Ball.GeodesicPoints(e1.Start, e1.End, 2 * m_div); points2 = H3Models.Ball.GeodesicPoints(e2.Start, e2.End, 2 * m_div); } else { points1 = H3Models.UHS.GeodesicPoints(e1.Start, e1.End, 2 * m_div); points2 = H3Models.UHS.GeodesicPoints(e2.Start, e2.End, 2 * m_div); } Sphere cellSphere = simplex[0]; Sphere vertexSphere = simplex[3]; // Because one vertex the facet triangle is hyperideal, it will actually look like a square. List <Vector3D[]> allPoints = new List <Vector3D[]>(); for (int i = 0; i < points1.Length; i++) { Vector3D p1 = points1[i]; Vector3D p2 = points2[i]; Vector3D[] arcPoints; if (i == points1.Length - 1) //if( false ) { // NOTE: This arc is not generally geodesic! // Or is it? arcPoints = ball ? H3Models.Ball.GeodesicPoints(p1, p2, m_div) : H3Models.UHS.GeodesicPoints(p1, p2, m_div); /*Circle3D arc = cellSphere.Intersection( vertexSphere ); * double angleTot = (p1 - arc.Center).AngleTo( p2 - arc.Center ); * arcPoints = Shapeways.CalcArcPoints( arc.Center, arc.Radius, p1, arc.Normal, -angleTot, div );*/ } else { Circle3D c = Circle3D.FromCenterAnd2Points(cellSphere.Center, p1, p2); double angleTot = (p1 - c.Center).AngleTo(p2 - c.Center); arcPoints = Shapeways.CalcArcPoints(cellSphere.Center, cellSphere.Radius, p1, c.Normal, -angleTot, m_div); } //Vector3D[] arcPoints = new Vector3D[] { p1, p2 }; allPoints.Add(arcPoints); } // Create the triangles for the patch. Mesh mesh = new Mesh(); for (int i = 0; i < allPoints.Count - 1; i++) { Vector3D[] arc1 = allPoints[i]; Vector3D[] arc2 = allPoints[i + 1]; for (int j = 0; j < arc1.Length - 1; j++) { // Points of (i,j) box; Vector3D p1 = arc1[j]; Vector3D p2 = arc2[j]; Vector3D p3 = arc1[j + 1]; Vector3D p4 = arc2[j + 1]; Mesh.Triangle tri1 = new Mesh.Triangle(p1, p2, p3); Mesh.Triangle tri2 = new Mesh.Triangle(p2, p4, p3); // We need to thicken after reflecting around, otherwise we can't apply a min thickness. /*Sphere normal = cellSphere; * Mesh.Triangle[] thickened1 = Thicken( tri1, normal ); * Mesh.Triangle[] thickened2 = Thicken( tri2, normal ); * mesh.Triangles.AddRange( thickened1 ); * mesh.Triangles.AddRange( thickened2 );*/ mesh.Triangles.Add(tri1); mesh.Triangles.Add(tri2); } } // AuxPoints will be used for multiple things. // - The first two points are for an an that will fill the gap where there is a missing face. // - We'll also store the points for the 4 edges of our fundamental triangle. List <Vector3D> auxPoints = new List <Vector3D>(); { var edge1 = allPoints.First(); var edge2 = allPoints.Last(); List <Vector3D> edge3 = new List <Vector3D>(), edge4 = new List <Vector3D>(); for (int i = 0; i < allPoints.Count; i++) { edge3.Add(allPoints[i][0]); edge4.Add(allPoints[i][allPoints[i].Length - 1]); } edge4.Reverse(); auxPoints.Add(e1.Start); auxPoints.Add(e1.End); auxPoints.AddRange(edge1.Reverse()); auxPoints.AddRange(edge2); auxPoints.AddRange(edge3); auxPoints.AddRange(edge4); } Vector3D cen = HoneycombPaper.InteriorPointBall; /* Reorientation code. Move this elsewhere. * * // Face centered orientation. * bool faceCentered = false; * if( faceCentered ) * SimplexCalcs.PrepForFacetCentering( p, q, simplex, ref cen ); * * Mobius mUHS = SimplexCalcs.FCOrientMobius( p, q ); * Mobius mBall = HoneycombPaper.FCOrientMobius( H3Models.UHSToBall( cellSphere ) ); * * simplex = simplex.Select( s => * { * s = H3Models.UHSToBall( s ); * //H3Models.TransformInBall2( s, mBall ); * return s; * } ).ToArray(); * * * { * for( int i = 0; i < mesh.Triangles.Count; i++ ) * { * Mesh.Triangle tri = mesh.Triangles[i]; * * if( faceCentered ) * { * tri.a = mUHS.ApplyToQuaternion( tri.a ); * tri.b = mUHS.ApplyToQuaternion( tri.b ); * tri.c = mUHS.ApplyToQuaternion( tri.c ); * } * * tri.a = H3Models.UHSToBall( tri.a ); * tri.b = H3Models.UHSToBall( tri.b ); * tri.c = H3Models.UHSToBall( tri.c ); * * if( faceCentered ) * { * tri.a = H3Models.TransformHelper( tri.a, mBall ); * tri.b = H3Models.TransformHelper( tri.b, mBall ); * tri.c = H3Models.TransformHelper( tri.c, mBall ); * } * mesh.Triangles[i] = tri; * } * * if( faceCentered ) * cen = H3Models.TransformHelper( cen, mBall ); * } */ // Now we need to reflect around this fundamental patch. H3.Cell[] simplices = GenCell(simplex, mesh, cen, auxPoints.ToArray(), ball); // Existing cells take precedence. foreach (H3.Cell c in simplices) { Vector3D t = c.Center; H3.Cell dummy; if (!complete.TryGetValue(t, out dummy)) { complete[t] = c; } } }
private static void CreateCellPovRay(HoneycombDef def, string filename, double t = 0) { int p = def.P; int q = def.Q; int r = def.R; //Vector3D trans = new Vector3D( 1.0/3, 0 ) * (2 + 2 * Math.Sin( Math.PI / 6 )) * t; //double scale = 1.8; Vector3D trans = new Vector3D(); double scale = 1.0; Vector3D[] sVerts = null; // SimplexCalcs.VertsBall( p, q, r ); Vector3D vUHS = H3Models.BallToUHS(SimplexCalcs.VertexPointBall(p, q, r)); // Just did this for everything. Non-general position working better and will make all heads consistent. scale = 2.0; if (Geometry2D.GetGeometry(q, r) != Geometry.Hyperbolic) // Vertex-centered if possible { scale = 1.0 / vUHS.Z; } //else if( Geometry2D.GetGeometry( p, q ) == Geometry.Hyperbolic ) // Make the biggest head somewhat smaller. // scale = 2.0; Vector3D cen = InteriorPointBall; /*var kleinVerts = sVerts.Select( v => HyperbolicModels.PoincareToKlein( v ) ); * Vector3D avg = new Vector3D(); * foreach( Vector3D v in kleinVerts ) * avg += v; * avg /= kleinVerts.Count(); * Vector3D cen = HyperbolicModels.KleinToPoincare( avg );*/ cen = H3Models.BallToUHS(cen); cen += trans; //cen *= scale; cen = H3Models.UHSToBall(cen); Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: false); // Apply transformations. simplex = simplex.Select(s => { Sphere.TranslateSphere(s, trans); Sphere.ScaleSphere(s, scale); return(H3Models.UHSToBall(s)); }).ToArray(); for (int i = 0; i < 4; i++) { if (simplex[i].IsPointInside(cen)) { simplex[i].Invert = true; } } Sphere[] simplexForColorScale = SimplexCalcs.Mirrors(p, q, r, moveToBall: true); CoxeterImages.Settings temp = AutoCalcScale(def, simplexForColorScale); int maxDepth = (int)temp.ColorScaling; //Random rand = new Random( p+q+r ); //int randOffset = rand.Next( maxDepth ); bool ball = true; bool dual = false; H3.Cell[] simplicesFinal = GenCell(simplex, null, cen, ball, dual); using (StreamWriter sw = File.CreateText(filename)) // We need to reuse this StreamWriter (vs. calling AppendSimplex) for performance. { sw.WriteLine("#include \"hyper_ball.pov\""); //int[] include = new int[] { 0, 1, 2, 3 }; int[] include = new int[] { 0 }; if (dual) { include = new int[] { 3 } } ; // Output the facets. foreach (H3.Cell cell in simplicesFinal) { Sphere[] facets = cell.Facets.Select(f => f.Sphere).ToArray(); if (m_toKlein) { facets = facets.Select(s => H3Models.BallToKlein(s)).ToArray(); } int depth = cell.Depths[0] + 1; Color c = Coloring.ColorAlongHexagon(maxDepth, depth); if (cell.Depths.Sum() % 2 == 0) { c = Coloring.Inverse(c); } PovRay.AddSimplex(sw, facets, cell.Center, include, filename, Coloring.ToVec(c)); } /*include = new int[] { 1, 2, 3 }; * foreach( H3.Cell cell in simplicesFinal ) * { * Sphere[] facets = cell.Facets.Select( f => f.Sphere ).ToArray(); * Color c = Color.Red; * Vector3D cv = Coloring.ToVec( c ); * cv.W = 0.9; * PovRay.AddSimplex( sw, facets, cell.Center, include, filename, cv ); * }*/ } // Output the edges/verts. bool includeEdges = false; if (includeEdges) { sVerts = sVerts.Select(v => { v = H3Models.BallToUHS(v); v += trans; v *= scale; return(H3Models.UHSToBall(v)); }).ToArray(); H3.Cell.Edge[] edges = Recurse.CalcEdges(simplex.Skip(1).ToArray(), new H3.Cell.Edge[] { new H3.Cell.Edge(sVerts[2], sVerts[3], order: false) }, new Recurse.Settings() { Threshold = 0.01 }); PovRay.WriteH3Edges(new PovRay.Parameters { AngularThickness = 0.01 }, edges, filename, append: true); HashSet <Vector3D> verts = new HashSet <Vector3D>(); foreach (H3.Cell.Edge e in edges) { verts.Add(e.End); } PovRay.WriteVerts(new PovRay.Parameters { AngularThickness = 0.02 }, Geometry.Hyperbolic, verts.ToArray(), filename, append: true); } }
public static void HoneycombFiniteVertexFig(HoneycombDef def) { // This will be used to remove duplicates. // Our faces will be doubled-up. We'll make a hash from one of the interior meshPoints. Dictionary <Vector3D, H3.Cell> complete = new Dictionary <Vector3D, H3.Cell>(); m_thresh = 0.07; HoneycombFiniteVertexFig(def, 3, complete); m_thresh = 0.02; HoneycombFiniteVertexFig(def, 2, complete); m_thresh = 0.007; HoneycombFiniteVertexFig(def, 1, complete); //m_thresh = 0.005; //CreateHoneycombSTL( def, 0, complete ); string filename = "cell.stl"; System.IO.File.Delete(filename); using (StreamWriter sw = File.AppendText(filename)) { foreach (H3.Cell cell in complete.Values) { //STL.AppendMeshToSTL( cell.Mesh, sw ); bool reverse = cell.Depths.Sum() % 2 == 1; Mesh m = new Mesh(); Sphere normal = cell.Facets[0].Sphere; foreach (Mesh.Triangle tri in cell.Mesh.Triangles) { Mesh.Triangle[] thickened = ThickenSimple(tri, normal); m.Triangles.AddRange(thickened); } if (reverse) { ReverseTris(m); } STL.AppendMeshToSTL(m, sw); System.Func <Vector3D, System.Tuple <Vector3D, Vector3D> > thickenFn = v => ThickenSimple(v, normal); int stride = (int)Math.Sqrt(cell.Mesh.Triangles.Count) + 1; Vector3D[] e1 = cell.AuxPoints.Skip(1 + 0 * stride).Take(stride).ToArray(); Vector3D[] e2 = cell.AuxPoints.Skip(1 + 1 * stride).Take(stride).ToArray(); Vector3D[] e3 = cell.AuxPoints.Skip(1 + 2 * stride).Take(stride).ToArray(); Mesh m1 = ThickenBoundary(e1, thickenFn), m2 = ThickenBoundary(e2, thickenFn), m3 = ThickenBoundary(e3, thickenFn); if (reverse) { ReverseTris(m1); ReverseTris(m2); ReverseTris(m3); } STL.AppendMeshToSTL(m1, sw); STL.AppendMeshToSTL(m2, sw); STL.AppendMeshToSTL(m3, sw); } } }
private static double AnimColorScaling(HoneycombDef imageData) { return(10); }
/// <summary> /// This generates a honeycomb by reflecting in 4 mirrors of the fundamental simplex. /// This "new" method is now old. /// </summary> public static void OneHoneycombNew(HoneycombDef imageData) { int p = imageData.P; int q = imageData.Q; int r = imageData.R; double thickness = 0.05; double thicknessSpherical = Spherical2D.s2eNorm(thickness); double thicknessHyperbolic = R3.Math.DonHatch.h2eNorm(thickness); double threshold = 1; H3.Cell.Edge[] edges = null; H3.Cell[] cellsToHighlight = null; Sphere[] simplex = null; Vector3D vertex = new Vector3D(); Geometry g = Util.GetGeometry(p, q, r); if (g == Geometry.Spherical) { thickness = thicknessSpherical /*.07 for 333*/ /* 0.05for 433*/ /*.025 for 533,335*/; threshold = 10000; simplex = SimplexCalcs.MirrorsSpherical(p, q, r); vertex = SimplexCalcs.VertexSpherical(p, q, r); // Ugly special casing for 333, since it has a vertex project to infinity. if (p == 3 && q == 3 && r == 3) { SpecialCase333(); } } else if (g == Geometry.Euclidean) { thickness = thickness / 2; threshold = 1 /*20*/; //SimplexCalcs.CalcEScale(); simplex = SimplexCalcs.MirrorsEuclidean(); Vector3D[] verts = SimplexCalcs.VertsEuclidean(); vertex = verts[2]; } else { thickness = thicknessHyperbolic; threshold = 0.01; simplex = SimplexCalcs.Mirrors(p, q, r); Vector3D[] verts = SimplexCalcs.VertsBall(p, q, r); vertex = verts[2]; //Vector3D[] simplexVerts = SimplexCalcs.VertsBall( p, q, r ); //H3.Cell.Edge edge = new H3.Cell.Edge( simplexVerts[2], simplexVerts[3] ); //H3.Cell.Edge edge = SimplexCalcs.HoneycombEdgeBall( p, q, r ); //H3.Cell.Edge[] startingEdges = new H3.Cell.Edge[] { edge }; //H3.Cell.Edge[] edges = Recurse.CalcEdgesSmart2( simplex, startingEdges ); // Vertex Centered. bool vertexCentered = false; if (vertexCentered) { Vector3D v = SimplexCalcs.VertexPointBall(p, q, r); v = H3Models.BallToUHS(v); double scale = 1.0 / v.Abs(); edges = edges.Select(e => { Vector3D start = H3Models.UHSToBall(H3Models.BallToUHS(e.Start) * scale); Vector3D end = H3Models.UHSToBall(H3Models.BallToUHS(e.End) * scale); return(new H3.Cell.Edge(start, end)); }).ToArray(); } // Code to show endpoints of 535 /*using( StreamWriter sw = File.CreateText( "535_points.pov" ) ) * { * HashSet<Vector3D> verts = new HashSet<Vector3D>(); * foreach( H3.Cell.Edge e in edges ) * { * verts.Add( Sterographic.SphereToPlane( e.Start ) ); * verts.Add( Sterographic.SphereToPlane( e.End ) ); * } * * foreach( Vector3D vert in verts ) * if( !Infinity.IsInfinite( vert ) ) * sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) ); * }*/ } // Recurse bool dual = false; { H3.Cell.Edge[] startingEdges = null; if (dual) { startingEdges = new H3.Cell.Edge[] { SimplexCalcs.DualEdgeBall(simplex) } } ; else { //startingEdges = new H3.Cell.Edge[] { SimplexCalcs.HoneycombEdgeBall( simplex, vertex ) }; Vector3D[] verts = SimplexCalcs.VertsEuclidean(); Vector3D v1 = verts[0] + 2 * verts[2]; // adjacent cube center Vector3D corner = verts[3]; startingEdges = new H3.Cell.Edge[] { new H3.Cell.Edge(v1, corner) }; } edges = Recurse.CalcEdges(simplex, startingEdges, new Recurse.Settings() { G = g, Threshold = threshold }); edges = edges.Where(e => { int sum = e.Depths.Count(d => d == 0); return(true); }).ToArray(); //CullHalfOfEdges( ref edges ); // No need to cull edges in spherical case. // This was just to generate some images for 350-cell paper. //edges = Cull120Cell( edges ); Simplex tet = new Simplex(); tet.Facets = simplex; if (dual) { H3.Cell.Edge[] oneDualCell = edges.Where(e => e.Depths[2] == 0).ToArray(); simplex = simplex.Skip(1).ToArray(); edges = Recurse.CalcEdges(simplex, oneDualCell, new Recurse.Settings() { G = g, Threshold = threshold }); int[] polyMirrors = new int[] { 0, 1, 3 }; H3.Cell startingCell = HoneycombGen.PolyhedronToHighlight(g, polyMirrors, tet, new Vector3D()); cellsToHighlight = Recurse.CalcCells(simplex, new H3.Cell[] { startingCell }); //cellsToHighlight = new H3.Cell[] { startingCell }; //cellsToHighlight = cellsToHighlight.Skip( 7 ).ToArray(); } else { int[] polyMirrors = new int[] { 1, 2, 3 }; H3.Cell startingCell = HoneycombGen.PolyhedronToHighlight(g, polyMirrors, tet, vertex); //cellsToHighlight = Recurse.CalcCells( simplex, new H3.Cell[] { startingCell } ); cellsToHighlight = new H3.Cell[] { startingCell }; } // Include just one cell? bool includeOne = false; if (includeOne) { edges = edges.Where(e => e.Depths[0] == 0).ToArray(); //cellsToHighlight = cellsToHighlight.Where( c => c.Depths[0] == 0 ).ToArray(); } } // Rotate bool rotate = false; if (rotate) { CompoundOfFive24Cells(ref edges); } // Write the file bool pov = true; if (pov) { string filename = string.Format("{0}{1}{2}.pov", p, q, r); PovRay.WriteEdges(new PovRay.Parameters() { AngularThickness = thickness }, g, edges, filename, append: false); //File.Delete( filename ); //PovRay.AppendFacets( cellsToHighlight, filename ); HashSet <Vector3D> verts = new HashSet <Vector3D>(); foreach (H3.Cell.Edge e in edges) { verts.Add(e.Start); verts.Add(e.End); } /*foreach( Vector3D v in verts ) * { * Vector3D t = v; * t.Normalize(); * t *= 0.9; * System.Diagnostics.Trace.WriteLine( string.Format( "light_source {{ <{0},{1},{2}> White*.2 }}", t.X, t.Y, t.Z ) ); * }*/ /* * // Include the standard pov stuff, so we can batch this. * string fileName = imageData.FormatFilename( string.Empty ); * using( StreamWriter sw = File.CreateText( fileName + ".pov" ) ) * { * sw.WriteLine( "#include \"C:\\Users\\hrn\\Documents\\roice\\povray\\paper\\H3.pov\"" ); * } * * bool dummy = true; // Doesn't matter for Pov-Ray, just Shapeways meshes. * H3.SaveToFile( fileName, edges, dummy, append: true ); */ } else { if (g == Geometry.Spherical) { edges = edges.Where(e => e.Start.Valid() && e.End.Valid() && !Infinity.IsInfinite(e.Start) && !Infinity.IsInfinite(e.End)).ToArray(); S3.EdgesToStl(edges); } else { throw new System.NotImplementedException(); } } }
private static void BatchRun(Settings config) { bool batchRun = true; if (!batchRun) { return; } /*HoneycombDef[] fullSet = GetFullImageSet().ToArray(); * foreach( HoneycombDef iData in fullSet ) * { * config.Angles = new int[] { iData.P, iData.Q, iData.R }; * OneImage( config ); * }*/ //int[] ps = new int[] { 3, 4, 5, 6, 7, 8, -1 }; //int[] qs = new int[] { 3 }; //int[] rs = new int[] { 3, 4, 5, 6, 7, 8, -1 }; int[] ps = new int[] { 3, 4, 5, 6, 7, 8, -1 }; int[] qs = new int[] { 3, 4, 5, 6, 7, 8, -1 }; int[] rs = new int[] { 3, 4, 5, 6, 7, 8, -1 }; //int[] rs = new int[] { 8, 9, 10, 11, 12, 13, 14, 15, 20, 25, 30 }; //int[] rs = new int[] { 3 }; foreach (int p in ps) { foreach (int q in qs) { foreach (int r in rs) { //if( !( Geometry2D.GetGeometry( p, q ) == Geometry.Hyperbolic || Geometry2D.GetGeometry( q, r ) == Geometry.Hyperbolic ) ) // continue; //if( !( Geometry2D.GetGeometry( p, q ) == Geometry.Spherical || Geometry2D.GetGeometry( q, r ) == Geometry.Spherical ) ) //continue; if (!((p == 7 && q == 3 && r == 3))) { continue; } //if( !(p==3) ) continue; //if( !(p ==4||p==5) ) continue; //if( q!=7 ) continue; //if( r!=5 ) continue; //if( r!=3 ) continue; //if( !(r==4 || r== 5)) continue; //if( Geometry2D.GetGeometry( q, r ) != Geometry.Spherical ) // continue; config.Angles = new int[] { p, q, r }; //OneImage( config ); string fileName = config.FileName("pov"); System.Console.WriteLine(fileName); if (File.Exists(fileName)) { System.Console.WriteLine("Skipping because it exists."); //continue; } HoneycombDef def = new HoneycombDef(p, q, r); CreateCellPovRay(def, fileName); config.Angles = new int[] { p, q, r }; //OneImage( config ); } } } }