private void PolytopeTypeChanged(object sender, SelectionChangedEventArgs e) { polytope = (Polytope)polytopeTypeBox.SelectedIndex; switch (polytope) { case Polytope.Simplex: dimensionControl.Maximum = maxSimplexDim; dimX = dimX > maxSimplexDim ? maxSimplexDim : dimX; dimensionControl.Value = dimX; break; case Polytope.Hypercube: dimensionControl.Maximum = maxHypercubeDim; dimX = dimX > maxHypercubeDim ? maxHypercubeDim : dimX; dimensionControl.Value = dimX; break; default: break; } ResetSimulation(null, null); }
/// <summary> /// Reads a file and returns polytope in cdd H-format /// </summary> /// <param name="src">File path</param> /// <returns>Polytope</returns> internal static Polytope read_from_file_cdd(string src) { Polytope p = null; try { List <Inequality> inequalitiesList = new List <Inequality>(); StreamReader sr = new StreamReader(src); string line; while ((line = sr.ReadLine()) != null) { string[] parts = Regex.Split(line.Trim(), "[ ]+"); double[] coefficients = new double[parts.Length]; coefficients[coefficients.Length - 1] = Convert.ToDouble(parts[0]); for (int i = 1; i < parts.Length; i++) { coefficients[i - 1] = -1 * Convert.ToDouble(parts[i]); } inequalitiesList.Add(new Inequality(coefficients)); } p = new Polytope(inequalitiesList.ToArray()); } catch (Exception E) { Console.WriteLine("File not found"); } return(p); }
/// <summary> /// The program will terminate exploring if it can't find another vertex in n^k iterations, /// where n is the current number of vertices /// and k is the number from the command line arguments /// </summary> /// <param name="path">Path to the file with a polytope</param> /// <param name="num">k</param> private static void start_k(string path, int num) { try { Polytope p = PolytopeReader.read_from_file_cdd(path); int iteration = 1; int number_of_vertices = 0; int last_discovery_iteration = 0; while (true) { p.explore(iteration, p.vertices); if (p.vertices.Count > number_of_vertices) { number_of_vertices = p.vertices.Count; last_discovery_iteration = iteration; } if (iteration - last_discovery_iteration > (number_of_vertices ^ num)) { break; } iteration++; } } catch (IOException e) { Console.WriteLine(e.Message); } }
Polytope GenerateDodeca() { Polytope icosa = GenerateIcosa(); Polytope dodeca = new Polytope(); foreach (var edge in icosa.polygons) { dodeca.Add(new Point { X = edge.Points(icosa).Sum(p => p.X) / 3, Y = edge.Points(icosa).Sum(p => p.Y) / 3, Z = edge.Points(icosa).Sum(p => p.Z) / 3 }); } dodeca.Add(new Polygon(new int[] { 16, 12, 8, 4, 0 })); for (int i = 0, j = 3; i < dodeca.points.Count; i += 4, j += 4) { dodeca.Add(new Polygon(new int[] { (i + 4) % 20, (i + 5) % 20, i + 3, i + 1, i })); dodeca.Add(new Polygon(new int[] { j, j - 1, (20 + j - 4) % 20 - 1, (20 + j - 4) % 20, i + 1 })); } dodeca.Add(new Polygon(new int[] { 2, 6, 10, 14, 18 })); return(dodeca); }
public void Init(ToolTab tab, Context context) { this.context = context; openFileDialog.InitialDirectory = Directory.GetCurrentDirectory(); openFileDialog.Filter = "obj files (*.obj)|*.obj"; openFileDialog.RestoreDirectory = true; Item.AddButton(tab.AddButton(Properties.Resources.Point, true), GeneratePoint, context); Item.AddButton(tab.AddButton(Properties.Resources.Cube, true), GenerateCube, context); Item.AddButton(tab.AddButton(Properties.Resources.Octahedron, true), GenerateOcta, context); Item.AddButton(tab.AddButton(Properties.Resources.Tetrahedron, true), GenerateTetra, context); Item.AddButton(tab.AddButton(Properties.Resources.Icosahedron, true), GenerateIcosa, context); Item.AddButton(tab.AddButton(Properties.Resources.Dodecahedron, true), GenerateDodeca, context); tab.AddButton(Properties.Resources.SplineBezier, false).ButtonClick += (a) => GenerateBezier(); MultiItem <Spline, Spline> .AddButton(tab.AddButton(Properties.Resources.Spline), () => new Spline(), (total, partial) => total.Add(partial.points.First()), GeneratePoint, context ); var load = tab.AddButton(Properties.Resources.Load, true); load.ButtonClick += b => ChangeFile(); Item.AddButton(load, GenerateObj, context); Polytope sun = Primitives.Octahedron(1); sun.Matreial = new SolidMaterial(Color.Yellow); sun.Apply(Matrix.Move(context.world.Sun)); var lastPos = context.world.Sun; var sunSettings = SunControl.Settings(point => { var newPos = point * (context.camera.location.Length() / 3); sun.Apply(Matrix.Move(newPos - lastPos)); lastPos = newPos; context.world.Sun = point; context.Redraw(); }); tab.Settings.Controls.Add(sunSettings); var sunButton = tab.AddButton(Properties.Resources.Sun); sunButton.ButtonClick += button => { sunSettings.Visible = true; context.world.entities.Add(sun); context.Redraw(); }; sunButton.ButtonDisable += button => { sunSettings.Visible = false; context.world.entities.Remove(sun); context.Redraw(); }; }
/** * \fn public GJKState(ref Polytope polytopeA, ref Polytope polytopeB) * * \brief Constructor * * \author Jaymie * \date 3/4/2019 * * \param [in] polytopeA The polytope a. * \param [in] polytopeB The polytope b. */ public GJKState(ref Polytope polytopeA, ref Polytope polytopeB) { IsCollided = false; FinishRun = false; Iteration = 0; _polytopeA = polytopeA; _polytopeB = polytopeB; CurrentSimplex = new Simplex(); MiscDebugLines = new List <Vector3>(); }
public static void Collided(ref GJKState state) { Polytope polytopeA = state.GetPolytopeA; Polytope polytopeB = state.GetPolytopeB; // More than 20 it if (state.Iteration > 20) { state.FinishRun = true; state.IsCollided = false; } else { // First GJK run if (state.CurrentSimplex.GetSize() == 0) { // Add the initial point Vector3 ta, tb; state.CurrentSimplex.Push(SupportFunction(polytopeB.GetCentre() - polytopeA.GetCentre(), polytopeA, polytopeB, out ta, out tb)); // Get a search direction from first point to origin if (state.LastDirection == Vector3.zero) { Vector3 directionAToO = new Vector3(0f, 0f, 0f) - state.CurrentSimplex.PeekBack(); state.LastDirection = directionAToO; } } // Second GJK run else if (state.CurrentSimplex.GetSize() == 1) { // Add next point Vector3 ta, tb; state.CurrentSimplex.Push(SupportFunction(state.LastDirection, polytopeA, polytopeB, out ta, out tb)); // Check if this point passes origin if (state.CurrentSimplex.PeekBack().IsInOppositeDirection(state.LastDirection)) { // This object is definably not colliding as the second point in the direction of // origin is not even passing it state.FinishRun = true; state.IsCollided = false; } } else // Begin it { ProcessSimplex(ref state); } } state.Iteration++; }
/// <summary> /// Start the process of exploring the face lattice untill the program finds a certain number of vertices /// </summary> /// <param name="path">Path to the file with a polytope</param> /// <param name="num">The program will explore untill it finds this number of vertices</param> private static void start_v(string path, int num) { try { Polytope p = PolytopeReader.read_from_file_cdd(path); int iteration = 1; while (p.vertices.Count < num) { p.explore(iteration, p.vertices); iteration++; } } catch (IOException e) { Console.WriteLine(e.Message); } }
/// <summary> /// Starts the process of exploring the face lattice till the user stops the program /// </summary> /// <param name="path">Path to the file with a polytope</param> private static void start(string path) { try { Polytope p = PolytopeReader.read_from_file_cdd(path); int iteration = 1; while (true) { p.explore(iteration, p.vertices); iteration++; } } catch (Exception E) { Console.WriteLine(E.Message); } }
public static List <Vector3> CalcMinkowskiSum(Polytope a, Polytope b) { List <Vector3> points = new List <Vector3>(); // Get vertices List <Vector3> verticesA = a.GetWorldPositionVertices(); List <Vector3> verticesB = b.GetWorldPositionVertices(); foreach (Vector3 vertexA in verticesA) { foreach (Vector3 vertexB in verticesB) { // A + -B points.Add(vertexA + (-vertexB)); } } return(points); }
void Update() { if ((Input.GetMouseButton(0) || Input.GetMouseButton(1)) && Time.time > nextAction) { nextAction = Time.time + Globals.actionRate; RaycastHitSpherical hit; if (PhysicsSpherical.Raycast(trans.lookRay, out hit, Mathf.PI)) { Polytope poly = hit.collider.GetComponent <Polytope>(); if (poly != null) { poly.Clicked(Input.GetMouseButton(0), Input.GetMouseButton(1), hit.triangleIndex, solidType); } } } if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } if (Input.GetKeyDown(KeyCode.Alpha1)) { solidType = (Solid)0; } if (Input.GetKeyDown(KeyCode.Alpha2)) { solidType = (Solid)1; } if (Input.GetKeyDown(KeyCode.Alpha3)) { solidType = (Solid)2; } if (Input.GetKeyDown(KeyCode.Alpha4)) { solidType = (Solid)3; } if (Input.GetKeyDown(KeyCode.Alpha5)) { solidType = (Solid)4; } if (Input.GetKeyDown(KeyCode.F1)) { Polytope poly = FindObjectOfType <Polytope>(); showEdges = !showEdges; poly.updateMeshFlag = true; if (showEdges) { foreach (Edge e in poly.edges) { e.contents = Solid.Black; } } else { foreach (Edge e in poly.edges) { e.contents = Solid.Empty; } } } if (Input.GetKeyDown(KeyCode.Equals)) { SceneManager.LoadScene(2); } if (Input.GetKeyDown(KeyCode.Minus)) { SceneManager.LoadScene(1); } if (Input.GetKeyDown(KeyCode.Alpha0)) { SceneManager.LoadScene(0); } }
Polytope MakeGraph(Node node, double xStart, double xEnd, double xStep, double yStart, double yEnd, double yStep) { var result = new Polytope(); int xDelta = 0; int yDelta = 0; for (double i = xStart; i <= xEnd; i += xStep) { xDelta += 1; yDelta = 0; for (double j = yStart; j <= yEnd; j += yStep) { yDelta += 1; result.Add(new Base3D.Point { X = i, Y = j, Z = node.Get(i, j) }); result.AddNormal(new Base3D.Point { X = -node.Dx().Get(i, j), Y = -node.Dy().Get(i, j), Z = 1 }.Normal()); result.AddNormal(new Base3D.Point { X = node.Dx().Get(i, j), Y = node.Dy().Get(i, j), Z = -1 }.Normal()); } } for (int i = 0; i < xDelta - 1; ++i) { for (int j = 0; j < yDelta - 1; ++j) { result.Add(new Polygon(new int[] { j + i * yDelta, j + (i + 1) * yDelta, (j + 1) + (i + 1) * yDelta, (j + 1) + i * yDelta }, new int[] { 2 * (j + i * yDelta), 2 * (j + (i + 1) * yDelta), 2 * ((j + 1) + (i + 1) * yDelta), 2 * ((j + 1) + i * yDelta) } )); result.Add(new Polygon(new int[] { j + i * yDelta, (j + 1) + i * yDelta, (j + 1) + (i + 1) * yDelta, j + (i + 1) * yDelta }, new int[] { 2 * (j + i * yDelta) + 1, 2 * ((j + 1) + i * yDelta) + 1, 2 * ((j + 1) + (i + 1) * yDelta) + 1, 2 * (j + (i + 1) * yDelta) + 1 } )); } } return(result); }
private static Vector3 SupportFunction(Vector3 direction, Polytope polytopeA, Polytope polytopeB, out Vector3 a, out Vector3 b) { a = polytopeA.GetFurthestPoint(direction); b = polytopeB.GetFurthestPoint(-direction); return(a + -b); }
public void Test() { Polytope p = GameObject.Find("600Cell").GetComponent <Polytope>(); Debug.Log(Vector4.Dot(p.faces[0].center, p.cells[p.faces[0].mcells[0]].center)); }
public void GenerateInternal( TilingConfig config, Polytope.Projection projection = Polytope.Projection.FaceCentered ) { this.TilingConfig = config; // Create a base tile. Tile tile = CreateBaseTile( config ); // Handle edge/vertex centered projections. if( projection == Polytope.Projection.VertexCentered ) { Mobius mobius = config.VertexCenteredMobius(); tile.Transform( mobius ); } else if( projection == Polytope.Projection.EdgeCentered ) { Mobius mobius = config.EdgeMobius(); tile.Transform( mobius ); } TransformAndAdd( tile ); List<Tile> tiles = new List<Tile>(); tiles.Add( tile ); Dictionary<Vector3D,bool> completed = new Dictionary<Vector3D,bool>(); completed[tile.Boundary.Center] = true; ReflectRecursive( tiles, completed ); FillOutIsometries( tile, m_tiles, config.Geometry ); FillOutIncidences(); }
public static Entity Parse(string file) { Directory.SetCurrentDirectory(Path.GetDirectoryName(file)); Polytope current = new Polytope(); Dictionary <string, BaseMaterial> mtl = new Dictionary <string, BaseMaterial>(); foreach (var s in File.ReadAllLines(file)) { if (String.IsNullOrEmpty(s)) { continue; } var lines = Regex.Split(s, @"\s").Where(l => !String.IsNullOrEmpty(l)).ToList(); string flag = lines[0]; if (flag == "v") { current.Add(new Base3D.Point { X = double.Parse(lines[1]), Y = -double.Parse(lines[3]), Z = double.Parse(lines[2]) }); } else if (flag == "vn") { current.AddNormal(new Base3D.Point { X = double.Parse(lines[1]), Y = -double.Parse(lines[3]), Z = double.Parse(lines[2]) }); } else if (flag == "vt") { current.Addtexture(( double.Parse(lines[1]), double.Parse(lines[2]) )); } else if (flag == "f") { var first = lines[1].Split('/'); var vertexes = lines.Skip(1).Select(l => Int32.Parse(l.Split('/')[0]) - 1).ToArray(); var textures = (first.Length > 1 && !String.IsNullOrEmpty(first[1])) ? lines.Skip(1).Select(l => Int32.Parse(l.Split('/')[1]) - 1).ToArray() : null; var normals = (first.Length > 2 && !String.IsNullOrEmpty(first[2])) ? lines.Skip(1).Select(l => Int32.Parse(l.Split('/')[2]) - 1).ToArray() : null; current.Add(new Polygon(vertexes, textures, normals)); } else if (flag == "mtllib") { try { var new_mtl = LoadMtl(Regex.Replace(s, @"\s*mtllib\s*(.*\S)\s*$", "$1")); mtl = new_mtl; } catch (Exception e) { MessageBox.Show($"Не вышло загрузить текстуры: {e.Message}", "Окошко-всплывашка", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else if (flag == "usemtl") { string matName = Regex.Replace(s, @"\s*usemtl\s*(.*\S)\s*$", "$1"); if (mtl.ContainsKey(matName)) { current.Matreial = mtl[matName]; } } } return(current); }