public ActionResult Fortunes(string providerName) { List<Fortune> fortunes = new List<Fortune>(); using (DbConnection connection = CreateConnection(providerName)) { connection.Open(); using (DbCommand command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM Fortune"; using (DbDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) { while (reader.Read()) { Fortune fortune = new Fortune { ID = reader.GetInt32(0), Message = reader.GetString(1) }; fortunes.Add(fortune); } } } } fortunes.Add(new Fortune { ID = 0, Message = "Additional fortune added at request time." }); fortunes.Sort(); return View("Fortunes", fortunes); }
//Generate the voronoi diagram using an external library public VoronoiDiagram GetVoronoi(List <Point> points) { _siteCells = new Dictionary <Point, Cell>(); var nrPoints = points.Count; var dataPoints = new Vector[nrPoints]; for (int i = 0; i < nrPoints; i++) { var point = points[i]; if (_siteCells.ContainsKey(point)) { continue; } dataPoints[i] = new Vector(point.X, point.Y); var cell = new Cell { SitePoint = point }; _siteCells.Add(point, cell); } //Create Voronoi Data using library var data = Fortune.ComputeVoronoiGraph(dataPoints); //data = BenTools.Mathematics.Fortune.FilterVG(data, 15); //Create Diagram _voronoi = new VoronoiDiagram(); _voronoi.HalfEdges = GenerateLines(data); _voronoi.VoronoiCells = GenerateCells(data); _voronoi.Sites = points; return(_voronoi); }
internal static Mesh PopulateMesh(Fortune fortune, Factory factory) { var mesh = factory.CreateMesh() as RayedMesh; // ReSharper disable once PossibleNullReferenceException if (mesh.Dimension != 2) { throw new MeshNavException("Voronoi requires 2D mesh"); } if (!mesh.VoronoiTrait) { throw new MeshNavException("Voronoi requires rayed mesh"); } foreach (var poly in fortune.Polygons) { ProcessPolygonEdges(poly, mesh); } return(mesh); }
public void LoadMap(LoadMapParams loadMapParams) { VoronoiGraph voronoiMap = null; for (int i = 0; i < 3; i++) { voronoiMap = Fortune.ComputeVoronoiGraph(loadMapParams.Points); foreach (Vector vector in loadMapParams.Points) { double v0 = 0.0d; double v1 = 0.0d; int say = 0; foreach (VoronoiEdge edge in voronoiMap.Edges) { if (edge.LeftData == vector || edge.RightData == vector) { double p0 = (edge.VVertexA[0] + edge.VVertexB[0]) / 2; double p1 = (edge.VVertexA[1] + edge.VVertexB[1]) / 2; v0 += double.IsNaN(p0) ? 0 : p0; v1 += double.IsNaN(p1) ? 0 : p1; say++; } } if (((v0 / say) < 400) && ((v0 / say) > 0)) { vector[0] = v0 / say; } if (((v1 / say) < 400) && ((v1 / say) > 0)) { vector[1] = v1 / say; } } } voronoiMap = Fortune.ComputeVoronoiGraph(loadMapParams.Points); ImproveMapData(voronoiMap, loadMapParams.Fix); }
public void TestEndurancePrice() { Fortune fortune = new Fortune(Fortune.FortuneId.ENDURANCE); fortune.updatePrice(); Assert.AreEqual(5, fortune.priceToNextLevel); fortune.level = 1; fortune.updatePrice(); Assert.AreEqual(10, fortune.priceToNextLevel); fortune.level = 2; fortune.updatePrice(); Assert.AreEqual(21, fortune.priceToNextLevel); fortune.level = 3; fortune.updatePrice(); Assert.AreEqual(43, fortune.priceToNextLevel); fortune.level = 10; fortune.updatePrice(); Assert.AreEqual(1315, fortune.priceToNextLevel); fortune.level = 100; fortune.updatePrice(); Assert.AreEqual(29703442, fortune.priceToNextLevel); }
// Voronoi methods private void makeVoronoiGraph() { List <Vector> VoronoiVectors = new List <Vector>(); foreach (TraversableNode node in boarderMap) { VoronoiVectors.Add(new Vector(node.getCoordinate().x, node.getCoordinate().y)); } VoronoiGraph nonPrunedGraph = Fortune.ComputeVoronoiGraph(VoronoiVectors); List <VoronoiEdge> toPrune = new List <VoronoiEdge>(); VoronoiGraph voronoiGraph = nonPrunedGraph; foreach (VoronoiEdge edge in voronoiGraph.Edges) { VEdgeList.Add(new VEdge( new Vector3((float)edge.VVertexA[0] * gridXSpacing + gridXSpacing / 2, 0, (float)edge.VVertexA[1] * gridYSpacing + gridYSpacing / 2), new Vector3((float)edge.VVertexB[0] * gridXSpacing + gridXSpacing / 2, 0, (float)edge.VVertexB[1] * gridYSpacing + gridYSpacing / 2))); } }
public async Task Execute_query_no_parameters_success() { using (var session = new PGSession(Host, Port, Database, User, Password)) { await session.StartAsync(); await session.PrepareAsync("q", "select id, message from fortune"); Fortune CreateFortune(List <Fortune> results) { var fortune = new Fortune(); results.Add(fortune); return(fortune); } void BindColumn(Fortune fortune, ReadBuffer readBuffer, int index, int length) { switch (index) { case 0: fortune.Id = readBuffer.ReadInt(); break; case 1: fortune.Message = readBuffer.ReadString(length); break; } } var fortunes = new List <Fortune>(); await session.ExecuteAsync("q", fortunes, CreateFortune, BindColumn); Assert.Equal(12, fortunes.Count); } }
public void TestGetMultiplierAsString() { Assert.AreEqual("0", Fortune.getMultiplierAsString(1)); Assert.AreEqual("25", Fortune.getMultiplierAsString(1.25)); Assert.AreEqual("50", Fortune.getMultiplierAsString(1.5)); Assert.AreEqual("72", Fortune.getMultiplierAsString(1.725)); Assert.AreEqual("87", Fortune.getMultiplierAsString(1.8724)); Assert.AreEqual("80", Fortune.getMultiplierAsString(1.8)); Assert.AreEqual("150", Fortune.getMultiplierAsString(2.5)); Assert.AreEqual("2900", Fortune.getMultiplierAsString(30)); Assert.AreEqual("50K", Fortune.getMultiplierAsString(501)); Assert.AreEqual("500K", Fortune.getMultiplierAsString(5001)); Assert.AreEqual("5M", Fortune.getMultiplierAsString(50001)); /*for (int i=0; i <= 100000; i++) // Check that no value is wrongly approximated as .99999 * { * float mult = 1 + 0.2f * i; * string multString = Fortune.getMultiplierAsString(mult); * if (multString.EndsWith("9")) * { * Debug.Log(multString); * } * }*/ }
public ActionResult GetFortune1(Fortune fortuneCurrent) { var model = new Fortune(); Random r = new Random(); List <string> fortuneList = new List <string>(); fortuneList.Add("Test1"); fortuneList.Add("I"); fortuneList.Add("W"); fortuneList.Add("Y"); fortuneList.Add("G"); fortuneList.Add("I"); fortuneList.Add("C"); fortuneList.Add("Test2"); int index = r.Next(0, fortuneList.Count); //while(index == previousIndex) //{ // index = r.Next(0, fortuneList.Count); // if (index != previousIndex) // break; //} //fortuneCurrent.fortuneText = fortuneList[index]; //previousIndex = index; model.fortuneText = fortuneList[index]; fortuneCurrent.fortuneText = model.fortuneText; return(PartialView("_Fortune", model)); }
public VoronoiCell[] GenerateTileCells(int internalCellsCount) { var mapWidth = TilesSize.x; var mapHeight = TilesSize.y; var cells = new Dictionary <FortuneVoronoi.Common.Point, VoronoiCell>(); var dx = mapWidth / HorBorderSitesCnt / Resolution; var dy = mapHeight / VertBorderSitesCnt / Resolution; var internalSites = SitesGridGenerator.GenerateInternalSites(HorBorderSitesCnt, VertBorderSitesCnt, Resolution, internalCellsCount, (min, max) => new IntPoint(Random.Range(min, max), Random.Range(min, max))); if (!CachedBorders.ContainsKey(TilesSize)) { var borderSites = SitesGridGenerator.GenerateTileBorder(HorBorderSitesCnt, VertBorderSitesCnt, Resolution, (min, max) => new IntPoint(Random.Range(min, max), Random.Range(min, max))); // (int)((min + max) * 0.5f) CachedBorders.Add(TilesSize, borderSites); } foreach (var site in internalSites.Concat(CachedBorders[TilesSize]).Distinct()) { var x = site.X * dx; var y = site.Y * dy; var v = new FortuneVoronoi.Common.Point(x, y); cells.Add(v, new VoronoiCell { IsVisible = !site.IsBorder, Site = v }); } var graph = Fortune.ComputeVoronoiGraph(cells); return(cells.Values.Where(c => c.IsVisible && c.IsClosed).ToArray()); }
public void TestShieldEffect() { Fortune fortune = new Fortune(Fortune.FortuneId.SHIELD); fortune.level = 0; fortune.applyEffect(); Assert.AreEqual(0, Player.shields); Assert.AreEqual(150, Player.applyShieldDamageReduction(150)); fortune.level = 1; fortune.applyEffect(); Assert.AreEqual(.051f, Player.shields, 1E-3f); Assert.AreEqual(142, Player.applyShieldDamageReduction(150)); fortune.level = 2; fortune.applyEffect(); Assert.AreEqual(.1f, Player.shields, 1E-5f); Assert.AreEqual(135, Player.applyShieldDamageReduction(150)); fortune.level = 3; fortune.applyEffect(); Assert.AreEqual(.146f, Player.shields, 1E-3f); Assert.AreEqual(128, Player.applyShieldDamageReduction(150)); fortune.level = 10; fortune.applyEffect(); Assert.AreEqual(.409f, Player.shields, 1E-3f); Assert.AreEqual(89, Player.applyShieldDamageReduction(150)); }
public static VCircleEvent CircleCheckDataNode(VDataNode n, double ys) { var l = LeftDataNode(n); var r = RightDataNode(n); if (l == null || r == null || l.DataPoint.Equals(r.DataPoint) || l.DataPoint.Equals(n.DataPoint) || n.DataPoint.Equals(r.DataPoint)) { return(null); } if (Fortune.Ccw(l.DataPoint[0], l.DataPoint[1], n.DataPoint[0], n.DataPoint[1], r.DataPoint[0], r.DataPoint[1], false) <= 0) { return(null); } var center = Fortune.CircumCircleCenter(l.DataPoint, n.DataPoint, r.DataPoint); var vc = new VCircleEvent { NodeN = n, NodeL = l, NodeR = r, CenterX = center[0], CenterY = center[1], Valid = true }; if (vc.Y > ys || Math.Abs(vc.Y - ys) < 1e-10) { return(vc); } return(null); }
public World(string countriesFile, string citiesFolder) { var bordersTemp = new Dictionary <string, string[]>(); var missing = new List <string>(); using (var s = File.OpenText(countriesFile)) { while (!s.EndOfStream) { var l = s.ReadLine(); var sections = l?.Split('\t'); var c = new Country(); if (sections == null) { continue; } c.Name = sections[0]; var stats = sections[1].Split(','); c.Population = int.Parse(stats[0]); c.Density = double.Parse(stats[1]); c.GdpPerCapita = double.Parse(stats[2]); stats = sections[2].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (bordersTemp.ContainsKey(c.Name)) { Console.WriteLine($"Possible Duplicate: {c.Name}."); } else if (stats.Any()) { bordersTemp.Add(c.Name, stats); } c.Ocean = bool.Parse(sections[3]); _countries.Add(c); } } foreach (var country in _countries) { var highwaysTemp = new Dictionary <City, string[]>(); //Load cities if (File.Exists($".\\{citiesFolder}\\{country.Name}.dat")) { using (var s = File.OpenText($".\\{citiesFolder}\\{country.Name}.dat")) { while (!s.EndOfStream) { var str = s.ReadLine()?.Split('\t'); if (country.Cities.Any(o => o.Name == str?[0])) { continue; } var coor = str?[1].Split(',').Select(double.Parse).ToArray() ?? new[] { 0.0, 0.0 }; var c = new City(str?[0], country, coor[0], coor[1]); highwaysTemp.Add(c, str?[2].Split(',')); country.Cities.Add(c); } } foreach (var city in country.Cities) { if (!highwaysTemp.ContainsKey(city)) { continue; } foreach (var s in highwaysTemp[city].Where(s => s != city.Name)) { if (country.Cities.Count(o => o.Name == s) == 0) { Console.WriteLine($"Missing city: '{s}'."); } else { city.BorderCities.Add(country.Cities.First(o => o.Name == s)); } } } } else { Console.WriteLine($"Missing city file {country.Name}.dat"); } _countries.AsParallel().Where(o => o.Cities.Count > 0).SelectMany(o => ConvexHull.Create(o.Cities).Points).ForEach(o => o.IsHull = true); //Load borders if (!bordersTemp.ContainsKey(country.Name)) { continue; } foreach (var s in bordersTemp[country.Name]) { if (_countries.Count(o => o.Name == s) == 0) { if (!missing.Contains(s)) { missing.Add(s); } country.BorderCountries.Add(new Country { Name = s }); } else { country.BorderCountries.AddRange(_countries.Where(o => o.Name == s)); } } } // Outbound foreach (var source in _countries.Where(o => o.Cities.Count != 0 && o.BorderCountries.Count != 0)) { foreach (var source1 in source.BorderCountries.Where(o => o.Cities.Count != 0 && !source.Outbound.ContainsKey(o))) { var graph = Fortune.ComputeVoronoiGraph(source.Cities.Union(source1.Cities).Where(o => o.IsHull).Select(o => new Vector(o.Position) { Tag = o })); var voronoiEdge = graph.Edges.Where(o => ((City)o.LeftData.Tag).Country != ((City)o.RightData.Tag).Country) .MinBy(o => Connection <City> .Distance((City)o.LeftData.Tag, (City)o.RightData.Tag)); var rightCity = (City)voronoiEdge.RightData.Tag; var leftCity = (City)voronoiEdge.LeftData.Tag; source.Outbound[source1] = leftCity.Country != source ? rightCity : leftCity; source1.Outbound[source] = rightCity.Country != source1 ? leftCity : rightCity; } } }
private SRandom _rndGen; //random generator //class constractor public Island(int width, int height, int relaxTime, int centerNum, int riverNum, float maxElevation, float mainStreamLengthRatio, //typical: 0.02 float subStreamLengthRatio, //typical: 0.5 float riverSplitFreq, //typical: 0.2 int seed = 0) { this.width = width; this.height = height; this.relaxationTime = relaxTime; this.num_of_centers = centerNum; this.num_of_rivers = riverNum; this._maxElevation = maxElevation; if (mainStreamLengthRatio < 0f || mainStreamLengthRatio > 0.2f) { throw new ArgumentOutOfRangeException("ratio must be between 0 and 0.2"); } _mainStreamLength = (int)Math.Floor(Math.Max(width, height) * mainStreamLengthRatio); if (subStreamLengthRatio < 0f || subStreamLengthRatio > 1f) { throw new ArgumentOutOfRangeException("ratio must be between 0 and 1"); } _subStreamLength = (int)Math.Floor(_mainStreamLength * subStreamLengthRatio); if (_riverSplitFreq < 0f || _riverSplitFreq > 1f) { throw new ArgumentOutOfRangeException("frequency must be between 0 and 1"); } _riverSplitFreq = riverSplitFreq; _rndGen = new SRandom(seed); centers = random_centers(width, height, num_of_centers); VoronoiGraph vg = Fortune.ComputeVoronoiGraph(centers); //run voronoi diagram algorithm for (int i = 0; i < centers.Count; i++) //Initialize and store IslandTiles { Tiles[centers[i]] = new IslandTile(centers[i], vg, width, height); } //call improveRandomPoints function "relaxation" times for (int re = 0; re < relaxationTime; re++) { centers = improveRandomPoints(Tiles, centers); VoronoiGraph vGraph = Fortune.ComputeVoronoiGraph(centers); Tiles = new Dictionary <Vector, IslandTile>(); for (int j = 0; j < centers.Count; j++) { Tiles[centers[j]] = new IslandTile(centers[j], vGraph, width, height); } } NN = new NearestNeighbor(centers);//builded kdtree foreach (var item in Tiles.Values) { if (item.center.data[0] < (width / 10) || item.center.data[0] > (width - width / 10) || item.center.data[1] < (width / 10) || item.center.data[1] > (width - width / 10)) { item.iswater = true; item.elevation = 0; foreach (var c in item.corners) { c.elevation = 0; // totalcorners[c.position] = c; //water.Add(c); } ocean.Add(item); } else { land.Add(item); } } //spreading ocean area int waterspreadcount = 0; foreach (var item in Tiles.Values) { if (!item.iswater) { foreach (var i in item.neighbors) { if (Tiles[i].iswater) { item.iswater = true; item.elevation = 0; foreach (var c in item.corners) { c.elevation = 0; //totalcorners[c.position] = c; //water.Add(c); } ocean.Add(item); land.Remove(item); waterspreadcount++; } if (waterspreadcount > (num_of_centers / 3)) { break; } } } if (waterspreadcount > (num_of_centers / 3)) { break; } } //remove one tile island foreach (var item in Tiles.Values) { float sum_of_elevation = 0; foreach (var c in item.corners) { sum_of_elevation += c.elevation; } if (sum_of_elevation == 0) { item.iswater = true; item.elevation = 0; ocean.Add(item); land.Remove(item); } } //-----calculate coastline------------------------ foreach (var item in land) { foreach (var c in item.corners) { if (c.elevation == 0) { shore.Add(c); item.isshore = true; } } } //calculate elevation for corners foreach (var t in Tiles.Values) { if (!t.iswater) { float sum_elevation = 0; foreach (var c in t.corners) { float minDistToShore = float.MaxValue; foreach (var s in shore) { float distToShore = (float)Math.Sqrt((c.position - s.position).data[0] * (c.position - s.position).data[0] + (c.position - s.position).data[1] * (c.position - s.position).data[1]); if (minDistToShore > distToShore) { minDistToShore = distToShore; } } c.elevation = minDistToShore * minDistToShore / _maxElevation; c.elevation = Math.Min(c.elevation, _maxElevation); sum_elevation += c.elevation; // totalcorners[c.position] = c; } t.elevation = sum_elevation / t.corners.Count; } } //store total corners /*foreach(var item in Tiles.Values) * { * foreach (var c in item.corners) * totalcorners.Add(c); * }*/ //landcenters foreach (var item in land) { landcenters.Add(item.center); } rivers = GenerateRivers();//generate rivers foreach (var ri in rivers) { River.findDischarge(ri);//get discharge for every corner } //put discharge information in it's tile foreach (var kc in River.keeprivercorners) { foreach (var t in kc.touches) { t.hasriver = true; foreach (var c in t.corners) { if (c.position == kc.position) { c.discharge = kc.discharge; } break; } } } StoreBiome();//set biome type for each tile //from now on, all data of a tile are generated. }
public static Image CreateImage(VoronoiDiagramContext context, params IEnumerable <Point>[] inputs) { IEnumerable <IEnumerable <Vector> > dataPoints = inputs.Select( input => input.Select( point => new Vector(point.XCoordinate, point.YCoordinate) ) ); double factorX = context.Width / (context.MaxX - context.MinX); double factorY = context.Height / (context.MaxY - context.MinY); double factor = Math.Min(factorX, factorY); double minX = context.MinX - context.Width * (0.5 / factor - 0.5 / factorX); double minY = context.MinY - context.Height * (0.5 / factor - 0.5 / factorY); dataPoints = dataPoints.Select(points => points.Select(vector => new Vector( (vector[0] - minX) * factor, (vector[1] - minY) * factor ))); PointF toPoint(Vector vector) => new PointF( (float)vector[0], (float)vector[1] ); RectangleF toRectangle(Vector vector, float radius) => new RectangleF( (float)(vector[0]) - radius, (float)(vector[1]) - radius, radius * 2f, radius * 2f ); var image = new Bitmap(context.Width, context.Height); var linePen = new Pen(context.LineColor); var dataPointBrushes = context.DataPointsColors.Select(color => new SolidBrush(color)); var surface = Graphics.FromImage(image); surface.Clear(context.BackgroundColor); surface.SmoothingMode = SmoothingMode.HighQuality; try { VoronoiGraph graph = Fortune.ComputeVoronoiGraph(dataPoints.First().Distinct()); double infiniteLength = context.Width + context.Height; foreach (var edge in graph.Edges) { Vector left = edge.VVertexA; Vector right = edge.VVertexB; if (edge.IsPartlyInfinite) { Vector extension = edge.DirectionVector * infiniteLength; if (left == Fortune.VVInfinite) { left = edge.FixedPoint - extension; } if (right == Fortune.VVInfinite) { right = edge.FixedPoint + extension; } } surface.DrawLine(linePen, toPoint(left), toPoint(right)); } } catch (Exception) {} var target = dataPoints.Zip( dataPointBrushes.Zip( context.DataPointsRadii, (brush, radius) => new { brush, radius }), (points, style) => new { points, style } ).Reverse(); foreach (var data in target) { foreach (var point in data.points) { surface.FillEllipse(data.style.brush, toRectangle(point, data.style.radius)); } } return(image); }
private void rbtDelaunay_CheckedChanged(object sender, EventArgs e) { Bitmap bmp = Fortune.GetDelaunayTriangulation(640, 480, points); pbxVisialization.Image = bmp; }
private void rbtVoronoi_CheckedChanged(object sender, EventArgs e) { Bitmap bmp = Fortune.GetVoronoyMap(640, 480, points); pbxVisialization.Image = bmp; }
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> /// Starts plan generation process /// </summary> public void Generate() { var datapoints = new List <Vector>(Parameters.PolygonsCount); var r = new Random(Parameters.GridSeed); for (int i = 0; i < Parameters.PolygonsCount; i++) { datapoints.Add(new Vector(r.Next(0, Parameters.MapSize.X), r.Next(0, Parameters.MapSize.Y))); } var graph = Fortune.ComputeVoronoiGraph(datapoints); for (int i = 0; i < Parameters.RelaxCount; i++) { Relax(graph, datapoints); graph = Fortune.ComputeVoronoiGraph(datapoints); } FillMap(graph); { // adding elevation data var elevationNoise = new SimplexNoise(new Random(Parameters.ElevationSeed)); elevationNoise.SetParameters(0.0008, SimplexNoise.InflectionMode.NoInflections, SimplexNoise.ResultScale.ZeroToOne); foreach (var poly in this) { var noiseVal = elevationNoise.GetNoise2DValue(poly.Center.X, poly.Center.Y, 4, 0.8); var col = 255 / noiseVal.MaxValue * noiseVal.Value; poly.Elevation = (int)col; } //// elevate each corner //if (!Parameters.CenterElevation) // ElevateCorners(); } if (Parameters.CenterElevation) { var poly = GetAtPoint(new Point(Parameters.MapSize.X / 2, Parameters.MapSize.Y / 2)); poly.Elevation = 200; StartPropagation(poly, 15); } // making island { //r = new Random((int)voronoiSeedNumeric.Value); var borderElevation = 80; var step = 20; for (int x = 0; x < Parameters.MapSize.X; x += 5) { var poly = GetAtPoint(new Point(x, 0)); poly.Elevation = borderElevation;// r.Next(0, 100); StartPropagation(poly, step); poly = GetAtPoint(new Point(x, Parameters.MapSize.Y)); poly.Elevation = borderElevation;// r.Next(0, 100); StartPropagation(poly, step); } for (int y = 0; y < Parameters.MapSize.Y; y += 5) { var poly = GetAtPoint(new Point(0, y)); poly.Elevation = borderElevation;// r.Next(0, 100); StartPropagation(poly, step); poly = GetAtPoint(new Point(Parameters.MapSize.X, y)); poly.Elevation = borderElevation;// r.Next(0, 100); StartPropagation(poly, step); } } ElevateCorners(); #region Moisturizing { var noise = new SimplexNoise(new Random(Parameters.ElevationSeed)); noise.SetParameters(0.0008d, SimplexNoise.InflectionMode.NoInflections, SimplexNoise.ResultScale.ZeroToOne); foreach (var poly in this) { var noiseVal = noise.GetNoise2DValue(poly.Center.X, poly.Center.Y, 2, 0.8); var col = 100 / noiseVal.MaxValue * noiseVal.Value; poly.Moisture = (int)col; foreach (var corner in poly.Corners) { noiseVal = noise.GetNoise2DValue(corner.Point.X, corner.Point.Y, 2, 0.8); col = 2 / noiseVal.MaxValue * noiseVal.Value; corner.WaterFlow = (int)col; } } // fix heights foreach (var poly in this) { foreach (var neighbor in poly.Neighbors) { if (poly.Elevation == neighbor.Elevation) { neighbor.Elevation = (int)neighbor.Neighbors.Average(n => n.Elevation); } } } // calculate rivers _corners1 = new HashSet <Corner>(); // get unique corners foreach (var poly in this) { foreach (var corner in poly.Corners) { if (!_corners1.Contains(corner) && corner.Polygons.Find(p => p.Elevation <= 127) == null) { _corners1.Add(corner); } } } var list = new List <Corner>(_corners1); list.Sort(new CornerHeightComparer()); // propagate flow foreach (var corner in list) { // find lowest edge Edge lowestEdge = corner.Edges[0]; int height = lowestEdge.GetOpposite(corner).Elevation; for (int i = 0; i < corner.Edges.Count; i++) { var tmp = corner.Edges[i].GetOpposite(corner).Elevation; if (tmp < height) { height = tmp; lowestEdge = corner.Edges[i]; } } lowestEdge.WaterFlow += corner.WaterFlow; lowestEdge.GetOpposite(corner).WaterFlow += corner.WaterFlow; } // remove rivers that not going to oceans _waterCorners = new List <Corner>(); foreach (var poly in this) { foreach (var corner in poly.Corners) { int solid = corner.Polygons.Count(p => p.Elevation > 127); if (solid == 2) { _waterCorners.Add(corner); } } } // collect all correct edges _rivers.Clear(); foreach (var waterCorner in _waterCorners) { var root = new RiverBranch(); CollectRiver(waterCorner, root); if (!root.Final) { _riverRoots.Add(root); } } // fix river flows // stage 1: remove all flows foreach (var riverBranch in _riverRoots) { EnumerateTree(riverBranch, b => { if (b.Edge != null) { b.Edge.WaterFlow = 0; } }); } // stage 2: reflow it foreach (var riverBranch in _riverRoots) { FillRiver(riverBranch); } // remove all non-river foreach (var poly in this) { foreach (var edge in poly.Edges) { if (edge.WaterFlow > 0 && !_rivers.Contains(edge)) { edge.WaterFlow = 0; } } } // update moisture for polygons foreach (var poly in this) { if (poly.Elevation > 127) { poly.Moisture = poly.Neighbors.Sum(p => { var v = p.Neighbors.Sum(n => n.Edges.Sum(ed => ed.WaterFlow > 0 ? 1 : 0)); v = v + p.Neighbors.Sum(n => n.Elevation < 127 && !n.Ocean ? 3 : 0); return(p.Edges.Sum(ed => ed.WaterFlow > 0 ? 1 : 0) + v); }); } } } #endregion // detect ocean { SetOcean(GetAtPoint(new Point(0, 0))); SetOcean(GetAtPoint(new Point(Parameters.MapSize.X, 0))); SetOcean(GetAtPoint(new Point(0, Parameters.MapSize.Y))); SetOcean(GetAtPoint(new Point(Parameters.MapSize.X, Parameters.MapSize.Y))); } // set biomes { foreach (var poly in this) { if (poly.Elevation > 127) { poly.Biome = _biome.GetBiomeWith(poly.Elevation, poly.Moisture > _biome.Moisture.Maximum ? _biome.Moisture.Maximum : poly.Moisture); } } } //find coastline foreach (var polygon in this) { foreach (var edge in polygon.Edges) { Polygon poly; Polygon poly2; if (((poly = edge.Polygons.Find(p => p.Elevation > 127)) != null) && ((poly2 = edge.Polygons.Find((p => p.Elevation <= 127))) != null)) { poly.Coast = true; poly2.Coast = true; edge.Coast = true; } } } }
private void Canvas1_OnMouseDown(object sender, MouseButtonEventArgs e) { var rand = new Random(); var result = new List <int>(); var check = new HashSet <int>(); for (int i = 0; i < 2000; i++) { Int32 curValue = rand.Next(0, 4000); while (check.Contains(curValue)) { curValue = rand.Next(0, 4000); } result.Add(curValue); check.Add(curValue); } //generate points inside our rectangle for our voronoi generator var datapointlist = new List <Vector>(); for (int i = 0; i < 1000; i++) { datapointlist.Add(new Vector(result[i], result[i + 1000])); } IEnumerable <Vector> datapoints = datapointlist; var vgraph = new VoronoiGraph(); vgraph = Fortune.ComputeVoronoiGraph(datapoints); foreach (var vertex in vgraph.Vertizes) { } var R = 0; var G = 0; var B = 0; foreach (var edge in vgraph.Edges) { if (R < 255) { R++; } if (R == 255 && G < 255) { G++; } if (R == 255 && G == 255 && B < 255) { B++; } var brush = new SolidColorBrush(Color.FromArgb(255, (byte)R, (byte)G, (byte)B)); var poly = new Line() { X1 = edge.LeftData[0], Y1 = edge.LeftData[1], X2 = edge.RightData[0], Y2 = edge.RightData[1], Stroke = brush, StrokeThickness = 1 }; canvas1.Children.Add(poly); canvas1.InvalidateVisual(); canvas1.UpdateLayout(); } }
public async Task Draw(params string[] text) { await ReplyAsync(Fortune.fortune()); }
// Create a basic set of public List <TectonicPlate> GeneratePlates() { // Spawn some random cell centers within a grid. // Add one row and column outside of the map so no cells inside the map are border cells. List <TectonicPlate> plates = new List <TectonicPlate>(); for (int left = -PlateSize; left < MapSize.x + PlateSize; left += PlateSize) { for (int bottom = -PlateSize; bottom < MapSize.y + PlateSize; bottom += PlateSize) { int right = left + PlateSize; int top = bottom + PlateSize; plates.Add(new TectonicPlate { Center = new ivec2(rand.Next(left, right), rand.Next(bottom, top)), AngularVelocity = (float)rand.NextDouble() * maxPlateAngluarVelocity, LinearVelocity = new vec2((float)rand.NextDouble() * maxPlateLinearVelocity, (float)rand.NextDouble() * maxPlateLinearVelocity), BaseHeight = (float)rand.NextDouble() + 1f }); } } // Compute voronoi triangulation for plate edges var plateVectors = new Dictionary <Vector, TectonicPlate>(); foreach (var tectonicPlate in plates) { var center = new Vector(tectonicPlate.Center.x, tectonicPlate.Center.y); plateVectors[center] = tectonicPlate; } VoronoiGraph graph = Fortune.ComputeVoronoiGraph(plateVectors.Keys); foreach (var edge in graph.Edges) { ivec2 a = new ivec2((int)edge.VVertexA[0], (int)edge.VVertexA[1]); ivec2 b = new ivec2((int)edge.VVertexB[0], (int)edge.VVertexB[1]); // Ignore edges into infinity. We generate cells outside of the map so we have only finite edges in the mep if (a.x == Int32.MaxValue || a.x == Int32.MinValue || a.y == Int32.MaxValue || a.y == Int32.MinValue || b.x == Int32.MaxValue || b.x == Int32.MinValue || b.y == Int32.MaxValue || b.y == Int32.MinValue) { continue; } a.x = Math.Min(Math.Max(-200, a.x), MapSize.x + 200); a.y = Math.Min(Math.Max(-200, a.y), MapSize.y + 200); b.x = Math.Min(Math.Max(-200, b.x), MapSize.x + 200); b.y = Math.Min(Math.Max(-200, b.y), MapSize.y + 200); // left and right cells of the edges given by the fortune voronoi implementation are incorrect, compute the correct cells again ivec2 middle = (a + b) / 2; // Find the two plate centers closest to the edge middle point List <TectonicPlate> neighborCells = new List <TectonicPlate>(); neighborCells.AddRange(plates.OrderBy(p => (p.Center - middle).Length).Take(2)); TectonicPlate left = neighborCells[0]; TectonicPlate right = neighborCells[1]; // left/right correct? if (EdgeAngle(neighborCells[0].Center, a, b) > 0) { right = neighborCells[0]; left = neighborCells[1]; } float mountainFactor = rand.NextFloat(-1f, 1f); var tectonicEdge = new TectonicEdge { A = a, B = b, LeftPlate = left, RightPlate = right, MountainFactor = mountainFactor }; left.Edges.Add(tectonicEdge); right.Edges.Add(tectonicEdge); } SavePlateImage(plates, "plates.svg"); return(plates); }
protected override int[] GenerateDataImpl(long x, long y, long width, long height) { int[] data = new int[width * height]; // Determine output values. int noneOutput = 0; int originalOutput = 1; int centerOutput = (this.Result == VoronoiResult.AllValues) ? 2 : 1; int edgeOutput = (this.Result == VoronoiResult.AllValues) ? 3 : (this.Result == VoronoiResult.EdgesAndOriginals) ? 2 : 1; // Scan through the size of the array, randomly creating points. List <Vector> points = new List <Vector>(); for (int i = -this.EdgeSampling; i < width + this.EdgeSampling; i++) { for (int j = -this.EdgeSampling; j < height + this.EdgeSampling; j++) { int s = this.GetRandomRange(x + i, y + j, 0, this.PointValue, this.Modifier); //long s = this.GetRandomLong(x + i, y + j) % this.PointValue; //if (s < 0) s = Math.Abs(s); //if (s < 0 || s >= this.PointValue) // throw new InvalidOperationException(); if (s == 0) { points.Add(new Vector(new double[] { i, j })); if (i >= 0 && i < width && j >= 0 && j < height) { if (this.Result == VoronoiResult.AllValues || this.Result == VoronoiResult.EdgesAndOriginals || this.Result == VoronoiResult.OriginalOnly) { data[i + j * width] = originalOutput; } } } } } // Skip computations if we are only outputting original scatter values. if (this.Result == VoronoiResult.OriginalOnly) { return(data); } // Compute the Voronoi diagram. VoronoiGraph graph = Fortune.ComputeVoronoiGraph(points); // Output the edges if needed. if (this.Result == VoronoiResult.AllValues || this.Result == VoronoiResult.EdgesAndOriginals || this.Result == VoronoiResult.EdgeOnly) { foreach (VoronoiEdge v in graph.Edges) { Vector a = v.VVertexA; Vector b = v.VVertexB; // Normalize vector between two points. double cx = 0, cy = 0; double sx = b[0] < a[0] ? b[0] : a[0]; double sy = b[0] < a[0] ? b[1] : a[1]; double mx = b[0] > a[0] ? b[0] : a[0]; double tx = b[0] > a[0] ? b[0] - a[0] : a[0] - b[0]; double ty = b[0] > a[0] ? b[1] - a[1] : a[1] - b[1]; double length = Math.Sqrt(Math.Pow(tx, 2) + Math.Pow(ty, 2)); tx /= length; ty /= length; // Iterate until we reach the target. while (sx + cx < mx)// && sy + cy < my) { if ((int)(sx + cx) >= 0 && (int)(sx + cx) < width && (int)(sy + cy) >= 0 && (int)(sy + cy) < height && data[(int)(sx + cx) + (int)(sy + cy) * width] == noneOutput) { data[(int)(sx + cx) + (int)(sy + cy) * width] = edgeOutput; } cx += tx; // b[0] > a[0] ? tx : -tx; cy += ty; // b[1] > a[1] ? ty : -ty; } } } // Output the center points if needed. if (this.Result == VoronoiResult.AllValues || this.Result == VoronoiResult.CenterOnly) { foreach (Vector v in graph.Vertizes) { if ((int)v[0] >= 0 && (int)v[0] < width && (int)v[1] >= 0 && (int)v[1] < height) { data[(int)v[0] + (int)v[1] * width] = centerOutput; } } } // Return the result. return(data); }
/// <summary> /// The Voronoi Graph calculation creates the lines that form a voronoi diagram. /// </summary> /// <param name="points">The points to use for creating the tesselation.</param> /// <param name="result">The output featureset.</param> /// <param name="cropToExtent">The normal polygons have sharp angles that extend like stars. /// Cropping will ensure that the original featureset extent plus a small extra buffer amount /// is the outer extent of the polygons. Errors seem to occur if the exact extent is used.</param> public static void VoronoiPolygons(IFeatureSet points, IFeatureSet result, bool cropToExtent) { double[] vertices = points.Vertex; VoronoiGraph gp = Fortune.ComputeVoronoiGraph(vertices); Extent ext = points.Extent; ext.ExpandBy(ext.Width / 100, ext.Height / 100); IEnvelope env = ext.ToEnvelope(); IPolygon bounds = env.ToPolygon(); // Convert undefined coordinates to a defined coordinate. HandleBoundaries(gp, env); for (int i = 0; i < vertices.Length / 2; i++) { List <VoronoiEdge> myEdges = new List <VoronoiEdge>(); Vector2 v = new Vector2(vertices, i * 2); foreach (VoronoiEdge edge in gp.Edges) { if (!v.Equals(edge.RightData) && !v.Equals(edge.LeftData)) { continue; } myEdges.Add(edge); } List <Coordinate> coords = new List <Coordinate>(); VoronoiEdge firstEdge = myEdges[0]; coords.Add(firstEdge.VVertexA.ToCoordinate()); coords.Add(firstEdge.VVertexB.ToCoordinate()); Vector2 previous = firstEdge.VVertexB; myEdges.Remove(myEdges[0]); Vector2 start = firstEdge.VVertexA; while (myEdges.Count > 0) { for (int j = 0; j < myEdges.Count; j++) { VoronoiEdge edge = myEdges[j]; if (edge.VVertexA.Equals(previous)) { previous = edge.VVertexB; Coordinate c = previous.ToCoordinate(); coords.Add(c); myEdges.Remove(edge); break; } // couldn't match by adding to the end, so try adding to the beginning if (edge.VVertexB.Equals(start)) { start = edge.VVertexA; coords.Insert(0, start.ToCoordinate()); myEdges.Remove(edge); break; } // I don't like the reverse situation, but it seems necessary. if (edge.VVertexB.Equals(previous)) { previous = edge.VVertexA; Coordinate c = previous.ToCoordinate(); coords.Add(c); myEdges.Remove(edge); break; } if (edge.VVertexA.Equals(start)) { start = edge.VVertexB; coords.Insert(0, start.ToCoordinate()); myEdges.Remove(edge); break; } } } for (int j = 0; j < coords.Count; j++) { Coordinate cA = coords[j]; // Remove NAN values if (double.IsNaN(cA.X) || double.IsNaN(cA.Y)) { coords.Remove(cA); } // Remove duplicate coordinates for (int k = j + 1; k < coords.Count; k++) { Coordinate cB = coords[k]; if (cA.Equals2D(cB)) { coords.Remove(cB); } } } foreach (Coordinate coord in coords) { if (double.IsNaN(coord.X) || double.IsNaN(coord.Y)) { coords.Remove(coord); } } if (coords.Count <= 2) { continue; } Polygon pg = new Polygon(coords); if (cropToExtent) { try { IGeometry g = pg.Intersection(bounds); IPolygon p = g as IPolygon; if (p != null) { Feature f = new Feature(p, result); f.CopyAttributes(points.Features[i]); } } catch (Exception) { Feature f = new Feature(pg, result); f.CopyAttributes(points.Features[i]); } } else { Feature f = new Feature(pg, result); f.CopyAttributes(points.Features[i]); } } return; }
public static async Task OnMessageCreated(DiscordClient _, MessageCreateEventArgs args) { if (DefaultHandlerFilter.IsFluff(args.Message)) { return; } /* * (╯°□°)╯︵ ┻━┻ * (ノ ゜Д゜)ノ ︵ ┻━┻ * (ノಠ益ಠ)ノ彡┻━┻ * (ノಥ益ಥ)ノ ┻━┻ * (ノಥДಥ)ノ︵┻━┻・/ * (ノ^_^)ノ┻━┻ * (/¯◡ ‿ ◡)/¯ ~ ┻━┻ * * this might look the same, but only because of the font choice * * ┻━┻ * ┻━┻ */ try { var content = args.Message.Content; if (content.Contains("🎲") && Regex.IsMatch(content, @"(🎲|\s)+")) { var count = 1; var idx = content.IndexOf("🎲"); while (idx < content.Length && (idx = content.IndexOf("🎲", idx + 1)) > 0) { count++; } EmpathySimulationHandler.Throttling.Set(args.Channel.Id, new List <DiscordMessage> { args.Message }, EmpathySimulationHandler.ThrottleDuration); await Misc.RollImpl(args.Message, $"{count}d6").ConfigureAwait(false); return; } if (content.Trim() == "🥠") { EmpathySimulationHandler.Throttling.Set(args.Channel.Id, new List <DiscordMessage> { args.Message }, EmpathySimulationHandler.ThrottleDuration); await Fortune.ShowFortune(args.Message, args.Author).ConfigureAwait(false); return; } if (!(content.Contains("┻━┻") || content.Contains("┻━┻"))) { return; } var tableIdx = content.IndexOf("┻━┻", StringComparison.Ordinal); if (tableIdx < 0) { tableIdx = content.IndexOf("┻━┻", StringComparison.Ordinal); } var faceIdx = content[..tableIdx].LastIndexOfAny(OpenParen);
public static VoronoiGraph Voronoi(List <Vector> vectors) { return(Fortune.ComputeVoronoiGraph(vectors)); }
/// <summary> /// Get the position with the largest view cone on a specific target and with respect to an input radius /// </summary> public static void GetOptimalPosition(float[] target, float radius) { List <float[]> neighbor_coords = new List <float[]>(); ArrayList neighbor_theta_phi = new ArrayList(); ArrayList neighbor_correspondance = new ArrayList(); float min_theta = 1000.0f; float max_theta = 0.0f; float min_phi = 1000.0f; float max_phi = 0.0f; // Get all the atoms inside the sphere centered on the target and of the input radius, translate them into polar coordinates for (int i = 0; i < MoleculeModel.atomsLocationlist.Count; i++) { double dist = Distance3f(MoleculeModel.atomsLocationlist[i], target); if (dist < radius) { neighbor_coords.Add(MoleculeModel.atomsLocationlist[i]); float[] atom = new float[3]; atom[0] = MoleculeModel.atomsLocationlist[i][0] - target[0]; atom[1] = MoleculeModel.atomsLocationlist[i][1] - target[1]; atom[2] = MoleculeModel.atomsLocationlist[i][2] - target[2]; float theta = (float)Math.Acos(atom[2] / dist); float phi = (float)Math.Atan2(atom[1], atom[0]); Vector theta_phi = new Vector(2); theta_phi[0] = theta; theta_phi[1] = phi; neighbor_theta_phi.Add(theta_phi); neighbor_correspondance.Add(i); // Debug.Log (theta_phi); theta_phi = new Vector(2); theta_phi[0] = theta + (float)Math.PI / 2; theta_phi[1] = phi + (float)Math.PI; neighbor_theta_phi.Add(theta_phi); // Debug.Log (theta_phi); theta_phi = new Vector(2); theta_phi[0] = theta + (float)Math.PI / 2; theta_phi[1] = phi; neighbor_theta_phi.Add(theta_phi); // Debug.Log (theta_phi); theta_phi = new Vector(2); theta_phi[0] = theta; theta_phi[1] = phi + (float)Math.PI; neighbor_theta_phi.Add(theta_phi); // Debug.Log (theta_phi); if (theta + (float)Math.PI / 2 > max_theta) { max_theta = theta + (float)Math.PI / 2; } if (theta < min_theta) { min_theta = theta; } if (phi + (float)Math.PI > max_phi) { max_phi = phi + (float)Math.PI; } if (phi < min_phi) { min_phi = phi; } } } // Debug.Log (neighbor_theta_phi.GetEnumerator().Current[0]+" "+neighbor_theta_phi.GetEnumerator().Current[1]); // Debug.Log (neighbor_theta_phi[1][0]+" "+neighbor_theta_phi[1][1]); // Debug.Log (neighbor_theta_phi[2][0]+" "+neighbor_theta_phi[2][1]); // Debug.Log (neighbor_theta_phi[3][0]+" "+neighbor_theta_phi[3][1]); StreamWriter sw = new StreamWriter(@"/Users/trellet/Dev/UnityMol_svn/trunk/Assets/neighbors.txt"); foreach (Vector neighbor in neighbor_theta_phi) { sw.WriteLine("" + neighbor[0] + " " + neighbor[1]); } sw.Close(); // int length = neighbor_theta_phi.Count; // for(int i=0; i<length; i++) // { // Vector theta_phi = new Vector(2); // theta_phi[0] = neighbor_theta_phi[i][0]+ (float) Math.PI; // theta_phi[1] = neighbor_theta_phi[i][1]+2*(float) Math.PI; // neighbor_theta_phi.Add (theta_phi); // theta_phi[0] = neighbor_theta_phi[i][0]+(float) Math.PI; // theta_phi[1] = neighbor_theta_phi[i][1]; // neighbor_theta_phi.Add (theta_phi); // theta_phi[0] = neighbor_theta_phi[i][0]; // theta_phi[1] = neighbor_theta_phi[i][1]+2*(float) Math.PI; // neighbor_theta_phi.Add (theta_phi); // } Debug.Log("Nb of neighbors: " + neighbor_theta_phi.Count); Debug.Log("Min/max theta/phi: " + min_theta + " " + max_theta + " " + min_phi + " " + max_phi); // Compute the Voronoi graph from the neighbors polar coordinates VoronoiGraph result = Fortune.ComputeVoronoiGraph(neighbor_theta_phi); MoleculeModel.atomsLocationlist.OrderBy(x => x[0]); Debug.Log(result.Vertizes.Count); StreamWriter sw2 = new StreamWriter(@"/Users/trellet/Dev/UnityMol_svn/trunk/Assets/vertices.txt"); BenTools.Data.HashSet temp = new BenTools.Data.HashSet(); foreach (Vector vert in result.Vertizes) { if (vert[0] > min_theta && vert[0] < max_theta && vert[1] < max_phi && vert[1] > min_phi) { sw2.WriteLine("" + vert[0] + " " + vert[1]); temp.Add(vert); } } sw2.Close(); result.Vertizes = temp; //double min_dist = 1000.0; double max_dist = 0.0; float[] best_pos = new float[2]; //float[] best_point = new float[2]; //float[] vertex = new float[2]; //float[] point = new float[2]; // Vector vert = new Vector(); //int c = 0; double distance = 0.0; Dictionary <double, float[]> vertices = new Dictionary <double, float[]>(); // Find the largest distance between each vertex and the closest point to each of them //// 1st METHOD (faster, use the edges that contain point information) foreach (VoronoiEdge edge in result.Edges) { //min_dist = 1000.0; if (edge.VVertexA[0] > min_theta && edge.VVertexA[0] < max_theta && edge.VVertexA[1] < max_phi && edge.VVertexA[1] > min_phi) { distance = Distance2f(edge.VVertexA, edge.LeftData); float[] t = new float[2]; t[0] = (float)edge.VVertexA[0]; t[1] = (float)edge.VVertexA[1]; vertices[distance] = t; if (distance > max_dist) { max_dist = distance; best_pos[0] = (float)edge.VVertexA[0]; best_pos[1] = (float)edge.VVertexA[1]; } } if (edge.VVertexB[0] > min_theta && edge.VVertexB[0] < max_theta && edge.VVertexB[1] < max_phi && edge.VVertexB[1] > min_phi) { distance = Distance2f(edge.VVertexB, edge.LeftData); float[] t = new float[2]; t[0] = (float)edge.VVertexA[0]; t[1] = (float)edge.VVertexA[1]; vertices[distance] = t; if (distance > max_dist) { max_dist = distance; best_pos[0] = (float)edge.VVertexB[0]; best_pos[1] = (float)edge.VVertexB[1]; } } } var list = vertices.Keys.ToList(); list.Sort(); float[] cartesian = new float[3]; for (int i = list.Count - 1; i > list.Count - 8; i--) { //Debug.Log(list[i]+": "+vertices[list[i]][0]+" "+vertices[list[i]][1]); cartesian[0] = (radius * (float)Math.Sin(vertices[list[i]][0]) * (float)Math.Cos(vertices[list[i]][1])) + target[0]; cartesian[1] = (radius * (float)Math.Sin(vertices[list[i]][0]) * (float)Math.Sin(vertices[list[i]][1])) + target[1]; cartesian[2] = (radius * (float)Math.Cos(vertices[list[i]][0])) + target[2]; Debug.Log(list[i] + ": " + cartesian[0] + " " + cartesian[1] + " " + cartesian[2]); } ////// 2nd METHOD (slower, all vertices vs all points) // foreach (Vector vert in result.Vertizes) // { // min_dist = 1000.0; // // foreach (Vector neighbor in neighbor_theta_phi) // { //// vertices[0] = (float) vert[0]; //// vertices[1] = (float) vert[1]; // // double dist = Distance2f(vert, neighbor); // // if (dist < min_dist) // { // min_dist = dist; // point[0] = (float) neighbor[0]; // point[1] = (float) neighbor[1]; // } // } // if (min_dist > max_dist) // { // max_dist = min_dist; // best_pos[0] = (float) vert[0]; // best_pos[1] = (float) vert[1]; // best_point[0] = point[0]; // best_point[1] = point[1]; // } // // } Debug.Log("Maximum distance: " + max_dist); Debug.Log("Theta and phi: " + best_pos[0] + " " + best_pos[1]); float[] best_pos_cart = new float[3]; //float[] best_pos_cart2 = new float[3]; //float[] best_pos_cart3 = new float[3]; //float[] best_pos_cart4 = new float[3]; // Convert polar coordinates of the best position to cartesian ones + shift to molecule system coordinates best_pos_cart[0] = (radius * (float)Math.Sin(best_pos[0]) * (float)Math.Cos(best_pos[1])) + target[0]; best_pos_cart[1] = (radius * (float)Math.Sin(best_pos[0]) * (float)Math.Sin(best_pos[1])) + target[1]; best_pos_cart[2] = (radius * (float)Math.Cos(best_pos[0])) + target[2]; Debug.Log("Best position: " + best_pos_cart[0] + " " + best_pos_cart[1] + " " + best_pos_cart[2]); // best_pos_cart2[0] = (radius * (float) Math.Sin(best_pos[0]-Math.PI) * (float) Math.Cos(best_pos[1])) + target[0]; // best_pos_cart2[1] = (radius * (float) Math.Sin(best_pos[0]-Math.PI) * (float) Math.Sin(best_pos[1])) + target[1]; // best_pos_cart2[2] = (radius * (float) Math.Cos(best_pos[0]-Math.PI)) + target[2]; // best_pos_cart3[0] = (radius * (float) Math.Sin(best_pos[0]-Math.PI) * (float) Math.Cos(best_pos[1]-2*Math.PI)) + target[0]; // best_pos_cart3[1] = (radius * (float) Math.Sin(best_pos[0]-Math.PI) * (float) Math.Sin(best_pos[1]-2*Math.PI)) + target[1]; // best_pos_cart3[2] = (radius * (float) Math.Cos(best_pos[0]-Math.PI)) + target[2]; // best_pos_cart4[0] = (radius * (float) Math.Sin(best_pos[0]) * (float) Math.Cos(best_pos[1]-2*Math.PI)) + target[0]; // best_pos_cart4[1] = (radius * (float) Math.Sin(best_pos[0]) * (float) Math.Sin(best_pos[1]-2*Math.PI)) + target[1]; // best_pos_cart4[2] = (radius * (float) Math.Cos(best_pos[0])) + target[2]; // Debug.Log("Best position2: "+best_pos_cart2[0]+" "+best_pos_cart2[1]+" "+best_pos_cart2[2]); // Debug.Log("Best position3: "+best_pos_cart3[0]+" "+best_pos_cart3[1]+" "+best_pos_cart3[2]); // Debug.Log("Best position4: "+best_pos_cart4[0]+" "+best_pos_cart4[1]+" "+best_pos_cart4[2]); // Place the camera at the new best position and make it face the target UIData.optim_view = true; maxCamera.optim_target = new Vector3(target[0], target[1], target[2]); maxCamera.optim_cam_position = new Vector3(best_pos_cart[0], best_pos_cart[1], best_pos_cart[2]); GameObject camera = GameObject.Find("LoadBox"); UIData.optim_view_start_point = camera.transform.position; UIData.start_time = Time.time; //camera.transform.position = new Vector3(best_pos_cart[0], best_pos_cart[1], best_pos_cart[2]); // Wait(); // camera.transform.position = new Vector3(best_pos_cart2[0], best_pos_cart2[1], best_pos_cart2[2]); // Wait(); // camera.transform.position = new Vector3(best_pos_cart3[0], best_pos_cart3[1], best_pos_cart3[2]); // Wait(); // camera.transform.position = new Vector3(best_pos_cart4[0], best_pos_cart4[1], best_pos_cart4[2]); //maxCamera.ghost_target = GameObject.Find("Target"); // camera.transform.LookAt(ghost_target.transform); //result.Vertizes }
private static Fortune[] GetFortunes() { var fortunes = new Fortune[] { new Fortune { Id = 1000, Text = "People are naturally attracted to you." }, new Fortune { Id = 1001, Text = "You learn from your mistakes... You will learn a lot today." }, new Fortune { Id = 1002, Text = "If you have something good in your life, don't let it go!" }, new Fortune { Id = 1003, Text = "What ever you're goal is in life, embrace it visualize it, and for it will be yours." }, new Fortune { Id = 1004, Text = "Your shoes will make you happy today." }, new Fortune { Id = 1005, Text = "You cannot love life until you live the life you love." }, new Fortune { Id = 1006, Text = "Be on the lookout for coming events; They cast their shadows beforehand." }, new Fortune { Id = 1007, Text = "Land is always on the mind of a flying bird." }, new Fortune { Id = 1008, Text = "The man or woman you desire feels the same about you." }, new Fortune { Id = 1009, Text = "Meeting adversity well is the source of your strength." }, new Fortune { Id = 1010, Text = "A dream you have will come true." }, new Fortune { Id = 1011, Text = "Our deeds determine us, as much as we determine our deeds." }, new Fortune { Id = 1012, Text = "Never give up. You're not a failure if you don't give up." }, new Fortune { Id = 1013, Text = "You will become great if you believe in yourself." }, new Fortune { Id = 1014, Text = "There is no greater pleasure than seeing your loved ones prosper." }, new Fortune { Id = 1015, Text = "You will marry your lover." }, new Fortune { Id = 1016, Text = "A very attractive person has a message for you." }, new Fortune { Id = 1017, Text = "You already know the answer to the questions lingering inside your head." }, new Fortune { Id = 1018, Text = "It is now, and in this world, that we must live." }, new Fortune { Id = 1019, Text = "You must try, or hate yourself for not trying." }, new Fortune { Id = 1020, Text = "You can make your own happiness." }, new Fortune { Id = 1021, Text = "The greatest risk is not taking one." }, new Fortune { Id = 1022, Text = "The love of your life is stepping into your planet this summer." }, new Fortune { Id = 1023, Text = "Love can last a lifetime, if you want it to." }, new Fortune { Id = 1024, Text = "Adversity is the parent of virtue." }, new Fortune { Id = 1025, Text = "Serious trouble will bypass you." }, new Fortune { Id = 1026, Text = "A short stranger will soon enter your life with blessings to share." }, new Fortune { Id = 1027, Text = "Now is the time to try something new." }, new Fortune { Id = 1028, Text = "Wealth awaits you very soon." }, new Fortune { Id = 1029, Text = "If you feel you are right, stand firmly by your convictions." }, new Fortune { Id = 1030, Text = "If winter comes, can spring be far behind?" }, new Fortune { Id = 1031, Text = "Keep your eye out for someone special." }, new Fortune { Id = 1032, Text = "You are very talented in many ways." }, new Fortune { Id = 1033, Text = "A stranger, is a friend you have not spoken to yet." }, new Fortune { Id = 1034, Text = "A new voyage will fill your life with untold memories." }, new Fortune { Id = 1035, Text = "You will travel to many exotic places in your lifetime." }, new Fortune { Id = 1036, Text = "Your ability for accomplishment will follow with success." }, new Fortune { Id = 1037, Text = "Nothing astonishes men so much as common sense and plain dealing." }, new Fortune { Id = 1038, Text = "Its amazing how much good you can do if you dont care who gets the credit." }, new Fortune { Id = 1039, Text = "Everyone agrees. You are the best." }, new Fortune { Id = 1040, Text = "LIFE CONSIST NOT IN HOLDING GOOD CARDS, BUT IN PLAYING THOSE YOU HOLD WELL." }, new Fortune { Id = 1041, Text = "Jealousy doesn''t open doors, it closes them!" }, new Fortune { Id = 1042, Text = "It''s better to be alone sometimes." }, new Fortune { Id = 1043, Text = "When fear hurts you, conquer it and defeat it!" }, new Fortune { Id = 1044, Text = "Let the deeds speak." }, new Fortune { Id = 1045, Text = "You will be called in to fulfill a position of high honor and responsibility." }, new Fortune { Id = 1046, Text = "The man on the top of the mountain did not fall there." }, new Fortune { Id = 1047, Text = "You will conquer obstacles to achieve success." }, new Fortune { Id = 1048, Text = "Joys are often the shadows, cast by sorrows." }, new Fortune { Id = 1049, Text = "Fortune favors the brave." } }; return(fortunes); }
private void ComputeVoronoi() { _graph = Fortune.ComputeVoronoiGraph(_pointList); }