} // used to search // Polygon must be convex and clockwise, brute force but it works. static public void FitInsideConvexPoly(List <Vector2> points, Vector2 comparepoint, Vector2 startsize, Vector2 offsets, ref float mindist, ref Vector2 bestpos, ref Vector2 bestsize, float minwidthallowed = 1, float scaling = 0.9F) { Vector2 startpoint = comparepoint; if (!InsidePolygon(points, startpoint)) // if given a point outside the polygon, no point starting there, pick the centroid { float area; startpoint = PolygonTriangulator.Centroid(points, out area); } while (startsize.X > minwidthallowed) { Vector2 trysize = startsize; startsize *= scaling; bool foundoneatthissize = false; for (int i = 0; i < 1000; i++) { Vector2 trypos = new Vector2(startpoint.X + FlipOffset(i / 50) * offsets.X, startpoint.Y + FlipOffset(i % 50) * offsets.Y); bool inside = PolygonTriangulator.InsidePolygon(points, trypos, trysize.X, trysize.Y); float fromcompare = (trypos - comparepoint).Length; //string debugline = String.Format(" Poly {0} At {1} {2} try {3} dist {4} inside {5} step {6}", polynum, trypos.X, trypos.Y, trysize, textfromgeocentre, inside, i); //writer.WriteLine(debugline); if (inside) { if (fromcompare < mindist) { mindist = fromcompare; bestpos = trypos; bestsize = trysize; //writer.WriteLine(String.Format(" {0} Best pos at {1} size {2} dist {3}", polynum, i, trysize, mindist)); foundoneatthissize = true; } } } if (foundoneatthissize) { break; } } }
// KEEP for debug for now.. #if false static public void Test() { ///EDDiscovery2._3DMap.PolygonTriangulator.Test(); if (true) { List <Vector2> points = new List <Vector2>(); points.Add(new Vector2(100, 100)); points.Add(new Vector2(100, 200)); points.Add(new Vector2(200, 200)); points.Add(new Vector2(200, 100)); Vector2 centroid = PolygonTriangulator.Centroid(points); Console.WriteLine("{0} ", centroid); } if (false) { List <Vector2> points = new List <Vector2>(); points.Add(new Vector2(0, 100)); points.Add(new Vector2(100, 200)); points.Add(new Vector2(100, 100)); points.Add(new Vector2(200, 200)); points.Add(new Vector2(300, 100)); points.Add(new Vector2(150, 0)); points.Add(new Vector2(0, 50)); List <List <Vector2> > res = PolygonTriangulator.Triangulate(points, false); foreach (List <Vector2> poly in res) { Console.WriteLine("Poly:"); foreach (Vector2 p in poly) { Console.WriteLine(" {0},{1}", p.X, p.Y); } } } Console.WriteLine("END"); }
public List <IData3DSet> AddGalMapRegionsToDataset(bool colourregions) { var polydataset = new PolygonCollection("regpolys", Color.White, 1f, OpenTK.Graphics.OpenGL.PrimitiveType.Triangles); // ORDER AND NUMBER v.Important var outlinedataset = new PolygonCollection("reglines", Color.White, 1f, OpenTK.Graphics.OpenGL.PrimitiveType.LineLoop); // DrawStars picks them out in a particular order var datasetbks = Data3DSetClass <TexturedQuadData> .Create("regtext", Color.White, 1f); if (EDDiscoveryForm.galacticMapping != null) { long gmotarget = TargetClass.GetTargetGMO(); int cindex = 0; foreach (GalacticMapObject gmo in EDDiscoveryForm.galacticMapping.galacticMapObjects) { if (gmo.galMapType.Enabled && gmo.galMapType.Group == GalMapType.GalMapGroup.Regions) { string name = gmo.name; Color[] array = new Color[] { Color.Red, Color.Green, Color.Blue, Color.Brown, Color.Crimson, Color.Coral, Color.Aqua, Color.Yellow, Color.Violet, Color.Sienna, Color.Silver, Color.Salmon, Color.Pink, Color.AntiqueWhite, Color.Beige, Color.DarkCyan, Color.DarkGray, Color.ForestGreen, Color.LightSkyBlue, Color.Lime, Color.Maroon, Color.Olive, Color.SteelBlue }; Color c = array[cindex++ % array.Length]; List <Vector2> polygonxz = new List <Vector2>(); // needs it in x/z and in vector2's foreach (Vector3 pd in gmo.points) { polygonxz.Add(new Vector2((float)pd.X, (float)pd.Z)); // can be concave and wound the wrong way.. } Vector2 size, avg; Vector2 centre = PolygonTriangulator.Centre(polygonxz, out size, out avg); // default geographic centre (min x/z + max x/z/2) used in case poly triangulate fails (unlikely) List <List <Vector2> > polys = PolygonTriangulator.Triangulate(polygonxz, false); // cut into convex polygons first - because we want the biggest possible area for naming purposes //Console.WriteLine("Region {0} decomposed to {1} ", name, polys.Count); Vector2 bestpos = centre; Vector2 bestsize = new Vector2(250, 250 / 5); if (polys.Count > 0) // just in case.. { centre = PolygonTriangulator.Centroids(polys); // weighted mean of the centroids //Bitmap map3 = DrawString(String.Format("O{0}", cindex - 1), Color.White, gmostarfont); TexturedQuadData ntext3 = TexturedQuadData.FromBitmap(map3, new PointData(centre.X, 0, centre.Y), TexturedQuadData.NoRotation, 2000, 500); datasetbks.Add(ntext3); float mindist = float.MaxValue; foreach (List <Vector2> points in polys) // now for every poly { if (colourregions) { Color regcol = Color.FromArgb(64, c.R, c.G, c.B); if (points.Count == 3) // already a triangle.. { polydataset.Add(new Polygon(points, 1, regcol)); //outlinedataset.Add(new Polygon(points, 1, Color.FromArgb(255, 255, 255, 0))); //DEBUG } else { List <List <Vector2> > polytri = PolygonTriangulator.Triangulate(points, true); // cut into triangles not polygons foreach (List <Vector2> pt in polytri) { polydataset.Add(new Polygon(pt, 1, regcol)); // outlinedataset.Add(new Polygon(pt, 1, Color.FromArgb(255, 255, 255, 0))); // DEBUG } } } //float area; Vector2 polycentrepos = PolygonTriangulator.Centroid(points,out area); Bitmap map2 = DrawString(String.Format("X") , Color.White, gmostarfont); TexturedQuadData ntext2 = TexturedQuadData.FromBitmap(map2, new PointData(polycentrepos.X, 0, polycentrepos.Y), TexturedQuadData.NoRotation, 1000, 200); datasetbks.Add(ntext2); PolygonTriangulator.FitInsideConvexPoly(points, centre, new Vector2(3000, 3000 / 5), new Vector2(200, 200), ref mindist, ref bestpos, ref bestsize, bestsize.X / 2); } } Bitmap map = DrawString(gmo.name, Color.White, gmostarfont); PointData bitmappos = new PointData(bestpos.X, 0, bestpos.Y); TexturedQuadData ntext = TexturedQuadData.FromBitmap(map, bitmappos, TexturedQuadData.NoRotation, bestsize.X, bestsize.Y); datasetbks.Add(ntext); outlinedataset.Add(new Polygon(polygonxz, 1, Color.FromArgb(255, 128, 128, 128))); } } } _datasets.Add(polydataset); _datasets.Add(outlinedataset); _datasets.Add(datasetbks); return(_datasets); }