public void Reset() { GL.Enable(EnableCap.LineSmooth); GL.Enable(EnableCap.PolygonSmooth); // GL.Enable(EnableCap.DepthTest); Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); int seeds = 1280; int extraSeeds = 512; Vector[] points = new Vector[seeds + extraSeeds]; double thetaOffset = Tau / 4; for (int i = 0; i < seeds + extraSeeds; i++) { double theta = (double)(i + 1) * Tau / Phi; double r = Math.Sqrt(i+1); double x = (r) * Math.Cos(theta + thetaOffset); double y = (r) * Math.Sin(theta + thetaOffset); points[i] = new Vector(new double[] { x, y }); } VoronoiGraph graph = Fortune.ComputeVoronoiGraph(points); cells = new SortedDictionary<Vector, List<VoronoiEdge>>(); foreach (VoronoiEdge edge in graph.Edges) { if (double.IsNaN(edge.VVertexA.X) || double.IsNaN(edge.VVertexA.Y) || double.IsNaN(edge.VVertexB.X) || double.IsNaN(edge.VVertexB.Y) ) continue; if (!cells.ContainsKey(edge.LeftData)) cells[edge.LeftData] = new List<VoronoiEdge>(); cells[edge.LeftData].Add(edge); if (!cells.ContainsKey(edge.RightData)) cells[edge.RightData] = new List<VoronoiEdge>(); cells[edge.RightData].Add(edge); Complex pA = new Complex(edge.VVertexA.X, edge.VVertexA.Y); Complex pB = new Complex(edge.VVertexB.X, edge.VVertexB.Y); int sampleCount = 2; Complex[] samples = new Complex[sampleCount]; samples[0] = pA; samples[sampleCount - 1] = pB; for (int i = 1; i < sampleCount - 1; i++) { double ratio = (double)i / sampleCount; samples[i] = pA * (1 - ratio) + pB * ratio; } } for (int i = 0; i < seeds; i++) { Queue<VoronoiEdge> edges = new Queue<VoronoiEdge>(cells.Values.ElementAt(i)); var firstEdge = edges.Dequeue(); List<Complex> polygonPoints = new List<Complex>(); polygonPoints.Add(new Complex(firstEdge.VVertexA.X * scale, firstEdge.VVertexA.Y * scale)); polygonPoints.Add(new Complex(firstEdge.VVertexB.X * scale, firstEdge.VVertexB.Y * scale)); while (edges.Count > 0) { var edge = edges.Dequeue(); Complex pA = new Complex(edge.VVertexA.X * scale, edge.VVertexA.Y * scale); Complex pB = new Complex(edge.VVertexB.X * scale, edge.VVertexB.Y * scale); if (polygonPoints[0] == pA) { polygonPoints.Insert(0, pB); continue; } if (polygonPoints[0] == pB) { polygonPoints.Insert(0, pA); continue; } if (polygonPoints[polygonPoints.Count - 1] == pA) { polygonPoints.Add(pB); continue; } if (polygonPoints[polygonPoints.Count - 1] == pB) { polygonPoints.Add(pA); continue; } edges.Enqueue(edge); } polygons.Add(polygonPoints); } for (int i = 0; i <= ModuloActor.MaxMod; i++) ModuloActor.Maps[i] = CreateIndexMap(i, cells); actors[0] = new ModuloActor(21, 0 / 3, new Color4(1f, 0.5f, 0.5f, 1f)); actors[1] = new ModuloActor(13, 1 / 3, new Color4(0.5f, 1f, 0.5f, 1f)); actors[2] = new ModuloActor(0, 2 / 3, new Color4(0.5f, 0.5f, 1f, 1f)); ModuloActor.AnnounceFibonaccis(); }
/// <summary> /// Called when it is time to render the next frame. Add your rendering code here. /// </summary> /// <param name="e">Contains timing information.</param> protected override void OnRenderFrame(FrameEventArgs e) { //GC.Collect(); // GC.WaitForPendingFinalizers(); base.OnRenderFrame(e); lastActualTime = actualTime; actualTime = Now; double elapsed = (actualTime - lastActualTime) * Speed; time += elapsed; // Console.WriteLine(string.Format("Frame:{0:F5} Avg:{1:F5}", time - oldTime, (time - startTime) / ++drawCount)); if (IsRandomizing && time - resetTime > resetDuration) { // Randomize(); resetTime = time; } if (joystickControl != null) { joystickControl.Sample(time); } mouseControl.Sample(); GL.ClearColor(Color4.Black); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); ModuloActor.UpdateAll(elapsed); FeedbackActor.UpdateAll(elapsed); var FeedbackActorMap = new Dictionary <int, FeedbackActor[]>(); if (FeedbackActor.AllActors != null) { FeedbackActorMap = FeedbackActor.AllActors .GroupBy(a => a.Index) .ToDictionary(g => g.Key, g => g.ToArray()) ; } for (int i = 0; i < polygons.Count; i++) { var color = new Color4( (float)actors[0].GetValue(i), (float)actors[1].GetValue(i), (float)actors[2].GetValue(i), 1f); if (FeedbackActorMap.ContainsKey(i)) { foreach (FeedbackActor actor in FeedbackActorMap[i]) { color = BlendColors(actor.GetColor(), new Color4(color.R, color.G, color.B, 1f)); } } var polygonPoints = polygons[i]; GL.Begin(BeginMode.TriangleFan); GL.Color4(color); for (int j = 0; j < polygonPoints.Count; j++) { GL.Vertex3(polygonPoints[j].Vector3d); } GL.End(); for (int j = 1; j < polygonPoints.Count; j++) { new TrimmedCircLine(polygonPoints[j - 1], polygonPoints[j]).DrawGL(new Color4(0.1f, 0.1f, 0.1f, 1)); } } // var random = new Random(); // new Complex(random.NextDouble()*scale, random.NextDouble()*scale).DrawGL(Color4.Wheat); //PolarDemo(time); // LoopDemo(mousePos.Re); // SaveGL(time.ToString("000000000.000000")); SwapBuffers(); }
private void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e) { bool isShift = SunflowerWindow.Keyboard[Key.LShift] || SunflowerWindow.Keyboard[Key.RShift]; bool isCtrl = SunflowerWindow.Keyboard[Key.LControl] || SunflowerWindow.Keyboard[Key.RControl]; switch (e.Key) { case Key.Number1: case Key.Keypad1: SunflowerWindow.Actors[0].Modulo += isShift ? -1 : 1; break; case Key.Number2: case Key.Keypad2: SunflowerWindow.Actors[1].Modulo += isShift ? -1 : 1; break; case Key.Number3: case Key.Keypad3: SunflowerWindow.Actors[2].Modulo += isShift ? -1 : 1; break; case Key.Number4: case Key.Keypad4: SunflowerWindow.Actors[0].Slope *= isShift ? 1 / 1.5 : 1.5; break; case Key.Number5: case Key.Keypad5: SunflowerWindow.Actors[1].Slope *= isShift ? 1 / 1.5 : 1.5; break; case Key.Number6: case Key.Keypad6: SunflowerWindow.Actors[2].Slope *= isShift ? 1 / 1.5 : 1.5; break; case Key.Number7: case Key.Keypad7: SunflowerWindow.Actors[0].Speed *= (isShift ? 1 / 1.5 : 1.5) * (isCtrl ? -1 : 1); break; case Key.Number8: case Key.Keypad8: SunflowerWindow.Actors[1].Speed *= (isShift ? 1 / 1.5 : 1.5) * (isCtrl ? -1 : 1); break; case Key.Number9: case Key.Keypad9: SunflowerWindow.Actors[2].Speed *= (isShift ? 1 / 1.5 : 1.5) * (isCtrl ? -1 : 1); break; case Key.S: ModuloActor.SwapSortedAll(); break; case Key.L: SunflowerWindow.Slope *= isShift ? 1 / 1.5 : 1.5; break; case Key.P: SunflowerWindow.Speed *= isShift ? 1 / 1.5 : 1.5; break; case Key.F: SunflowerWindow.ToggleFullscreen(); break; case Key.Escape: SunflowerWindow.Exit(); break; case Key.R: SunflowerWindow.Offset = Complex.Zero; SunflowerWindow.AngleOffset = 0; SunflowerWindow.Reset(); break; case Key.I: SunflowerWindow.IsInverting = !SunflowerWindow.IsInverting; SunflowerWindow.Reset(); break; case Key.M: SunflowerWindow.IsMoving = !SunflowerWindow.IsMoving; break; case Key.Tab: break; } }
public void Reset() { GL.Enable(EnableCap.LineSmooth); GL.Enable(EnableCap.PolygonSmooth); // GL.Enable(EnableCap.DepthTest); Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); int seeds = 1280; int extraSeeds = 512; Vector[] points = new Vector[seeds + extraSeeds]; double thetaOffset = Tau / 4; for (int i = 0; i < seeds + extraSeeds; i++) { double theta = (double)(i + 1) * Tau / Phi; double r = Math.Sqrt(i + 1); double x = (r) * Math.Cos(theta + thetaOffset); double y = (r) * Math.Sin(theta + thetaOffset); points[i] = new Vector(new double[] { x, y }); } VoronoiGraph graph = Fortune.ComputeVoronoiGraph(points); cells = new SortedDictionary <Vector, List <VoronoiEdge> >(); foreach (VoronoiEdge edge in graph.Edges) { if (double.IsNaN(edge.VVertexA.X) || double.IsNaN(edge.VVertexA.Y) || double.IsNaN(edge.VVertexB.X) || double.IsNaN(edge.VVertexB.Y) ) { continue; } if (!cells.ContainsKey(edge.LeftData)) { cells[edge.LeftData] = new List <VoronoiEdge>(); } cells[edge.LeftData].Add(edge); if (!cells.ContainsKey(edge.RightData)) { cells[edge.RightData] = new List <VoronoiEdge>(); } cells[edge.RightData].Add(edge); Complex pA = new Complex(edge.VVertexA.X, edge.VVertexA.Y); Complex pB = new Complex(edge.VVertexB.X, edge.VVertexB.Y); int sampleCount = 2; Complex[] samples = new Complex[sampleCount]; samples[0] = pA; samples[sampleCount - 1] = pB; for (int i = 1; i < sampleCount - 1; i++) { double ratio = (double)i / sampleCount; samples[i] = pA * (1 - ratio) + pB * ratio; } } for (int i = 0; i < seeds; i++) { Queue <VoronoiEdge> edges = new Queue <VoronoiEdge>(cells.Values.ElementAt(i)); var firstEdge = edges.Dequeue(); List <Complex> polygonPoints = new List <Complex>(); polygonPoints.Add(new Complex(firstEdge.VVertexA.X * scale, firstEdge.VVertexA.Y * scale)); polygonPoints.Add(new Complex(firstEdge.VVertexB.X * scale, firstEdge.VVertexB.Y * scale)); while (edges.Count > 0) { var edge = edges.Dequeue(); Complex pA = new Complex(edge.VVertexA.X * scale, edge.VVertexA.Y * scale); Complex pB = new Complex(edge.VVertexB.X * scale, edge.VVertexB.Y * scale); if (polygonPoints[0] == pA) { polygonPoints.Insert(0, pB); continue; } if (polygonPoints[0] == pB) { polygonPoints.Insert(0, pA); continue; } if (polygonPoints[polygonPoints.Count - 1] == pA) { polygonPoints.Add(pB); continue; } if (polygonPoints[polygonPoints.Count - 1] == pB) { polygonPoints.Add(pA); continue; } edges.Enqueue(edge); } polygons.Add(polygonPoints); } for (int i = 0; i <= ModuloActor.MaxMod; i++) { ModuloActor.Maps[i] = CreateIndexMap(i, cells); } actors[0] = new ModuloActor(21, 0 / 3, new Color4(1f, 0.5f, 0.5f, 1f)); actors[1] = new ModuloActor(13, 1 / 3, new Color4(0.5f, 1f, 0.5f, 1f)); actors[2] = new ModuloActor(0, 2 / 3, new Color4(0.5f, 0.5f, 1f, 1f)); ModuloActor.AnnounceFibonaccis(); }