public void Initialize(VPoint start, FortuneSite left, FortuneSite right) { Start = start; End = VPoint.Default; Left = left; Right = right; IsClipped = false; Neighbor = null; //for bounding box edges if (left == null || right == null) { return; } //from negative reciprocal of slope of line from left to right //ala m = (left.y -right.y / left.x - right.x) SlopeRise = left.X - right.X; SlopeRun = -(left.Y - right.Y); Intercept = null; if (SlopeRise.ApproxEqual(0) || SlopeRun.ApproxEqual(0)) { return; } Slope = SlopeRise / SlopeRun; Intercept = start.Y - Slope * start.X; }
/// <summary> /// given two real tri indices, /// put the VVerts into the allocated 4-elem array, /// 0 for triIdx0, 1-2 for vedge, 3 for triIdx1 /// </summary> private void _GetAsQuadVerts(int triIdx0, int triIdx1, VEdge vedge, VVert[] tmpVertArr) { VVert ev0 = vedge.GetVVert(0); VVert ev1 = vedge.GetVVert(1); GetVVertsFromRTri(triIdx0, out tmpVertArr[0], out tmpVertArr[1], out tmpVertArr[2]); // put the non-edge vert at idx-0 for (int specialVertIdx = 0; specialVertIdx < 3; ++specialVertIdx) { if (tmpVertArr[specialVertIdx] != ev0 && tmpVertArr[specialVertIdx] != ev1) { var tmp = tmpVertArr[0]; tmpVertArr[0] = tmpVertArr[specialVertIdx]; tmpVertArr[specialVertIdx] = tmp; break; } } GetVVertsFromRTri(triIdx1, out tmpVertArr[1], out tmpVertArr[2], out tmpVertArr[3]); // put the non-edge vert at idx-3 for (int specialVertIdx = 1; specialVertIdx < 4; ++specialVertIdx) { if (tmpVertArr[specialVertIdx] != ev0 && tmpVertArr[specialVertIdx] != ev1) { var tmp = tmpVertArr[3]; tmpVertArr[3] = tmpVertArr[specialVertIdx]; tmpVertArr[specialVertIdx] = tmp; break; } } }
// Runs whenever this grid needs to be reset public void Reset() { for (int row = 0; row < HEdge.GetLength(0); row++) { for (int col = 0; col < HEdge.GetLength(1); col++) { HEdge[row, col].GetComponent <Edge>().Reset(); } } for (int row = 0; row < VEdge.GetLength(0); row++) { for (int col = 0; col < VEdge.GetLength(1); col++) { VEdge[row, col].GetComponent <Edge>().Reset(); } } for (int row = 0; row < Box.GetLength(0); row++) { for (int col = 0; col < Box.GetLength(1); col++) { Box[row, col].GetComponent <Box>().Reset(); } } CompleteBoxCount = 0; }
void Start() { debuggers = new List <GameObject>(); particles = new List <VParticle>(); for (int i = 0; i < count; i++) { var p = new VParticle(Vector3.right * i); particles.Add(p); var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.localScale = Vector3.one * 0.25f; debuggers.Add(sphere); } ; for (int i = 0; i < count; i++) { if (i != count - 1) { var a = particles[i]; var b = particles[i + 1]; var e = new VEdge(a, b); a.Connect(e); b.Connect(e); } } simulator = new VerletSimulator(particles); }
public static Rectangle ToRectangle(this VEdge edge, out float angle) { var vector = edge.ToVector2(); angle = (float)Math.Atan2(vector.Y, vector.X); return(new Rectangle((int)edge.Start.X, (int)edge.Start.Y, (int)vector.Length(), 1)); }
// private method private void _PrepareEdgeIndices() { VMesh vmesh = VMesh.Instance; VVert[] allVVerts = vmesh.GetAllVVerts(); VEdge[] allVEdges = vmesh.GetAllVActiveEdges(); Dictionary <VVert, int> vert2idx = new Dictionary <VVert, int>(); for (int i = 0; i < allVVerts.Length; ++i) { VVert v = allVVerts[i]; vert2idx[v] = i; } m_EdgeIndices = new int[allVEdges.Length * 2]; for (int i = 0; i < allVEdges.Length; i++) { VEdge e = allVEdges[i]; VVert v0 = e.GetVVert(0); VVert v1 = e.GetVVert(1); int vidx0 = vert2idx[v0]; int vidx1 = vert2idx[v1]; m_EdgeIndices[i * 2] = vidx0; m_EdgeIndices[i * 2 + 1] = vidx1; } }
/// <summary> /// given an edge, and select the edge loop based on that /// </summary> public void Execute(VEdge vedge, Op op) { VVert v0 = vedge.GetVVert(0); VVert v1 = vedge.GetVVert(1); Execute(v0, v1, op); }
/// <summary> /// given world pos 'pt', find out the dist to given edge /// </summary> public static float DistPointToVEdge(Vector3 pt, VEdge vEdge) { Vector3 pos0 = vEdge.GetVVert(0).GetWorldPos(); Vector3 pos1 = vEdge.GetVVert(1).GetWorldPos(); return(GeoUtil.DistPointToLine(pt, pos0, pos1)); }
public RegionBorder(VEdge edge, GameObject border) { this.edge = edge; var instance = VoronoiGenerator.instance; edge.CreateNoisyEdge(edge.isRiver ? instance.biomeSettings.riverSubdivisions : instance.subdivisions); lineRenderer = border.GetComponent <LineRenderer>(); lineRenderer.useWorldSpace = false; if (edge.isRiver) { lineRenderer.startColor = BiomeSettings.RiverColor; lineRenderer.endColor = BiomeSettings.RiverColor; } else { lineRenderer.startColor = borderColor; lineRenderer.endColor = borderColor; } lineRenderer.sharedMaterial = new Material(Shader.Find("Sprites/Default")); lineRenderer.widthMultiplier = borderWidth; lineRenderer.numCapVertices = 4; lineRenderer.numCornerVertices = 4; lineRenderer.positionCount = edge.segments.Count; lineRenderer.SetPositions(edge.segments.ToArray()); border.transform.localPosition = borderZOffset; startCorner = edge.start; endCorner = edge.end; }
private void RecycleEdge(VEdge edge) { if (edge.Neighbor != null) { ObjectPool <VEdge> .Recycle(edge.Neighbor); } ObjectPool <VEdge> .Recycle(edge); }
public BoundaryCrossingEdge(VEdge edge, Vector2 intersect, bool isOnBorder = false, bool isCornerCutter = false, Corner borderCorner = null) { this.edge = edge; intersectPosition = intersect; this.isOnBorder = isOnBorder; this.isCornerCutter = isCornerCutter; this.borderCorner = borderCorner; }
private static VEdge AddEdgeForBoundingBox(VPoint startPoint, VPoint otherPoint, FortuneSite site, bool left) { var newEdge = new VEdge(startPoint, left ? site : null, left ? null : site) { End = otherPoint }; site.Cell.Add(newEdge); return(newEdge); }
void Start() { debuggers = new List <GameObject>(); particles = new List <VParticle>(); var offset = -count * 0.5f; for (int y = 0; y < count; y++) { for (int x = 0; x < count; x++) { var p = new VParticle(y * Vector3.forward + (Vector3.right * (x - offset))); particles.Add(p); var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.localScale = Vector3.one * 0.25f; debuggers.Add(sphere); } } for (int y = 0; y < count; y++) { if (y != count - 1) { for (int x = 0; x < count; x++) { var index = y * count + x; var c = particles[index]; if (x != count - 1) { var right = particles[index + 1]; var re = new VEdge(c, right); c.Connect(re); right.Connect(re); } var down = particles[index + count]; var de = new VEdge(c, down); c.Connect(de); down.Connect(de); } } else { for (int x = 0; x < count - 1; x++) { var index = y * count + x; var c = particles[index]; var right = particles[index + 1]; var re = new VEdge(c, right); c.Connect(re); right.Connect(re); } } } simulator = new VerletSimulator(particles); }
public void CreateActiveVEdgesList() { for (int i = 0; i < m_veLst.Count; ++i) { VEdge e = m_veLst[i]; if (e.IsActiveEdge) { m_activeVELst.Add(e); } } }
/// <summary> /// try to find VEdge connected to 'this' and 'rhs' /// if not found, return null /// </summary> public VEdge GetVEdge(VVert rhs) { for (int i = 0; i < m_veLst.Count; ++i) { VEdge e = m_veLst[i]; if (e.Contains(rhs)) { return(e); } } return(null); }
public VEdge CheckedGetVEdge(VVert rhs) { for (int i = 0; i < m_veLst.Count; ++i) { VEdge e = m_veLst[i]; if (e.Contains(rhs)) { return(e); } } Dbg.LogErr("VVerts.CheckedGetVEdge: failed to find an edge for: {0}=>{1}", this, rhs); return(null); }
private void DrawLine(SpriteBatch sb, VEdge vEdge) { float angle; var rect = vEdge.ToRectangle(out angle); sb.Draw(t, rect, //width of line, change this to make thicker line null, Color.Red, //colour of line angle, //angle of line (calulated above) new Vector2(0, 0), // point in line about which to rotate SpriteEffects.None, 0); }
private VEdge _CreateNewVEdge(VVert vv0, VVert vv1) { // new VEdge e = new VEdge(vv0, vv1); // add to vv0 vv0.AddVEdge(e); // add to vv1 vv1.AddVEdge(e); // add to vedgeCont m_VEdgeCont.Add(e); return(e); }
public static void Associate(Polygon polygon, VEdge edge) { if (polygon.Contains(edge)) { VoronoiGenerator.debugEdges.Add(edge); VoronoiGenerator.debugPolygons.Add(polygon); throw new Exception("polygon already contains this edge"); } polygon.Add(edge); if (edge.Contains(polygon)) { VoronoiGenerator.debugEdges.Add(edge); VoronoiGenerator.debugPolygons.Add(polygon); throw new Exception("edge already contains this polygon"); } edge.AddPolygon(polygon); }
private static bool ClipRay(VEdge edge, double minX, double minY, double maxX, double maxY) { var start = edge.Start; //horizontal ray if (edge.SlopeRise.ApproxEqual(0)) { if (!Within(start.Y, minY, maxY)) { return(false); } if (edge.SlopeRun > 0 && start.X > maxX) { return(false); } if (edge.SlopeRun < 0 && start.X < minX) { return(false); } if (Within(start.X, minX, maxX)) { if (edge.SlopeRun > 0) { edge.End = new VPoint(maxX, start.Y); } else { edge.End = new VPoint(minX, start.Y); } } else { if (edge.SlopeRun > 0) { edge.Start = new VPoint(minX, start.Y); edge.End = new VPoint(maxX, start.Y); } else { edge.Start = new VPoint(maxX, start.Y); edge.End = new VPoint(minX, start.Y); } } return(true); } //vertical ray if (edge.SlopeRun.ApproxEqual(0)) { if (start.X < minX || start.X > maxX) { return(false); } if (edge.SlopeRise > 0 && start.Y > maxY) { return(false); } if (edge.SlopeRise < 0 && start.Y < minY) { return(false); } if (Within(start.Y, minY, maxY)) { if (edge.SlopeRise > 0) { edge.End = new VPoint(start.X, maxY); } else { edge.End = new VPoint(start.X, minY); } } else { if (edge.SlopeRise > 0) { edge.Start = new VPoint(start.X, minY); edge.End = new VPoint(start.X, maxY); } else { edge.Start = new VPoint(start.X, maxY); edge.End = new VPoint(start.X, minY); } } return(true); } //works for outside Debug.Assert(edge.Slope != null, "edge.Slope != null"); Debug.Assert(edge.Intercept != null, "edge.Intercept != null"); var topX = new VPoint(CalcX(edge.Slope.Value, maxY, edge.Intercept.Value), maxY); var bottomX = new VPoint(CalcX(edge.Slope.Value, minY, edge.Intercept.Value), minY); var leftY = new VPoint(minX, CalcY(edge.Slope.Value, minX, edge.Intercept.Value)); var rightY = new VPoint(maxX, CalcY(edge.Slope.Value, maxX, edge.Intercept.Value)); //reject intersections not within bounds var candidates = new List <VPoint>(); if (Within(topX.X, minX, maxX)) { candidates.Add(topX); } if (Within(bottomX.X, minX, maxX)) { candidates.Add(bottomX); } if (Within(leftY.Y, minY, maxY)) { candidates.Add(leftY); } if (Within(rightY.Y, minY, maxY)) { candidates.Add(rightY); } //reject candidates which don't align with the slope for (var i = candidates.Count - 1; i > -1; i--) { var candidate = candidates[i]; //grab vector representing the edge var ax = candidate.X - start.X; var ay = candidate.Y - start.Y; if (edge.SlopeRun * ax + edge.SlopeRise * ay < 0) { candidates.RemoveAt(i); } } //if there are two candidates we are outside the closer one is start //the further one is the end if (candidates.Count == 2) { var ax = candidates[0].X - start.X; var ay = candidates[0].Y - start.Y; var bx = candidates[1].X - start.X; var by = candidates[1].Y - start.Y; if (ax * ax + ay * ay > bx * bx + by * by) { edge.Start = candidates[1]; edge.End = candidates[0]; } else { edge.Start = candidates[0]; edge.End = candidates[1]; } } //if there is one candidate we are inside if (candidates.Count == 1) { edge.End = candidates[0]; } //there were no candidates return(edge.End != null); }
// private method /// <summary> /// try to process v2 if possible (under given op) /// [v0 ==> v1 == v2] in this order /// </summary> private void _WalkSelect(VVert v0, VVert v1, Op op) { ////////////////////////////////////////////////// // 1. if v1 doesn't have exactly 4 vedges, return; // 2. take the vedge E that doesn't share VFace with vedge(v0,v1) // 3. select the other vvert v2 of E; // 4. iterate as _WalkSelect(v1, v2, op) ////////////////////////////////////////////////// VEdge thisEdge = v0.GetVEdge(v1); thisEdge.GetVFaces(m_tmpVFaces1); while (true) { // step 1 VELst veLst = v1.GetActiveVEdges(); if (veLst.Count != GOOD_EDGE_CNT) { //Dbg.Log("_WalkSelect: {0}=>{1}, veLst.Count not 4, is {2}", v0, v1, veLst.Count); break; //END } // step 2 VEdge thatEdge = null; for (int i = 0; i < GOOD_EDGE_CNT; ++i) { VEdge rhs = veLst[i]; if (rhs == thisEdge) { continue; } rhs.GetVFaces(m_tmpVFaces2); if (!_HasIntersect(m_tmpVFaces1, m_tmpVFaces2)) { thatEdge = rhs; break; //just out of edge loop } } // step 3 VVert v2 = null; if (thatEdge != null) { v2 = thatEdge.GetVVert(0); if (v2 == v1) { v2 = thatEdge.GetVVert(1); } // check for inf loop VEdge newEdge = v1.GetVEdge(v2); if (m_EdgeSet.Contains(newEdge)) { break; //END } m_EdgeSet.Add(newEdge); // modify selection if (op == Op.Add) { m_Selection.AddVVert(v2); } else { m_Selection.DelVVert(v2); } // step 4 v0 = v1; v1 = v2; thisEdge = thatEdge; Misc.Swap(ref m_tmpVFaces1, ref m_tmpVFaces2); } else { //Dbg.Log("_WalkSelect: {0}=>{1}, not found thatEdge", v0, v1); break; //END } } // end of while(true) }
public static Vector2 ToVector2(this VEdge edge) { return(edge.End.ToVector2() - edge.Start.ToVector2()); }
public ImageSource GetGodMap(string godString) { God currentG = this.pantheon.Gods.Where(e => e.ToString() == godString).First(); if (!currentG.Forgot) { if (mapPerlin == null) { GenPerlinMap(); } Bitmap bmp = new Bitmap(mapPerlin); using (Graphics g = Graphics.FromImage(bmp)) { foreach (Region site in currentG.Followers) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Color color = Color.FromArgb(150, site.God.Color.R, site.God.Color.G, site.God.Color.B); g.FillPolygon(new SolidBrush(color), tab); if (site.City) { if (site == site.God.Capitale) { g.FillEllipse(new SolidBrush(Color.White), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } else { g.FillEllipse(new SolidBrush(Color.Yellow), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } } } g.FillRectangle(new SolidBrush(Color.FromArgb(50, 255, 255, 255)), 0, 0, this.mapWidth, this.mapHeight); } return(ImageSourceFromBitmap(bmp)); } else { return(this.ImageSourceFromBitmap((Bitmap)Bitmap.FromFile("Assets/Background/BackgroundTemple.jpg"))); } }
public _ScoredEdge(float score, VEdge e) { this.score = score; this.vEdge = e; }
public ImageSource GetVoronoiGraph(System.Windows.Point position, bool delaunay = false) { if (mapPerlin == null) { GenPerlinMap(); } Bitmap bmp = new Bitmap(mapPerlin); using (Graphics g = Graphics.FromImage(bmp)) { int seed = -1; Region info = (Region)this.sites.First(); double distMin = this.mapWidth * 2; foreach (Region site in this.sites) { seed++; if (site.Kingdom != null && this.affSite) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Random rand = new Random(seed); Color color = Color.FromArgb(90, site.Kingdom.Color.R, site.Kingdom.Color.G, site.Kingdom.Color.B); g.FillPolygon(new SolidBrush(color), tab); } if (site.God != null && this.croyance) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Random rand = new Random(seed); Color color = Color.FromArgb(90, site.God.Color.R, site.God.Color.G, site.God.Color.B); g.FillPolygon(new SolidBrush(color), tab); } double dist = Math.Sqrt(Math.Pow(site.X - position.X, 2) + Math.Pow(site.Y - position.Y, 2)); if (distMin > dist) { info = site; distMin = dist; } if (site.City) { if (!site.Capital) { g.FillEllipse(new SolidBrush(Color.Crimson), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } else { g.FillEllipse(new SolidBrush(Color.Yellow), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } } if (delaunay) { foreach (var neighbor in site.Neighbors) { g.DrawLine(new System.Drawing.Pen(Color.Blue), (float)site.X, (float)site.Y, (float)neighbor.X, (float)neighbor.Y); } } } if (info != null && (this.croyance || this.affSite)) { string str = ""; if (this.affSite) { if (info.Kingdom == null) { str = "Les régions sauvages"; } else { str = info.Kingdom.Name; } } else if (this.croyance) { if (info.God == null) { str = "Non croyant"; } else { str = info.God.ToString(); } } Font font = new Font(System.Drawing.FontFamily.GenericMonospace, 12f, GraphicsUnit.Pixel); var width = str.Length * 7.5f; g.FillRectangle(new SolidBrush(Color.White), (position.X < this.mapWidth - width ? (float)(position.X) : (float)(position.X - width * 2)), (float)(position.Y - 10), width, font.Size + 2); g.DrawString(str, font, new SolidBrush(Color.Black), (position.X < this.mapWidth - width ? (float)(position.X) : (float)(position.X - width * 2)), (float)(position.Y - 10)); } if (voronoi) { foreach (VEdge vedge in vedges) { g.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Black), new System.Drawing.Point((int)vedge.Start.X, (int)vedge.Start.Y), new System.Drawing.Point((int)vedge.End.X, (int)vedge.End.Y)); } } } return(ImageSourceFromBitmap(bmp)); }
public ImageSource GetVoronoiGraph(bool delaunay = false) { if (mapPerlin == null) { GenPerlinMap(); } Bitmap bmp = new Bitmap(mapPerlin); using (Graphics g = Graphics.FromImage(bmp)) { int seed = -1; foreach (Region site in sites) { seed++; if (site.Kingdom != null && affSite) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Random rand = new Random(seed); Color color = Color.FromArgb(90, site.Kingdom.Color.R, site.Kingdom.Color.G, site.Kingdom.Color.B); g.FillPolygon(new SolidBrush(color), tab); } if (site.God != null && this.croyance) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Random rand = new Random(seed); Color color = Color.FromArgb(90, site.God.Color.R, site.God.Color.G, site.God.Color.B); g.FillPolygon(new SolidBrush(color), tab); } if (site.City) { if (!site.Capital) { g.FillEllipse(new SolidBrush(Color.Crimson), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } else { g.FillEllipse(new SolidBrush(Color.Yellow), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } } if (delaunay) { foreach (var neighbor in site.Neighbors) { g.DrawLine(new System.Drawing.Pen(Color.Blue), (float)site.X, (float)site.Y, (float)neighbor.X, (float)neighbor.Y); } } } if (voronoi) { foreach (VEdge vedge in vedges) { g.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Black), new System.Drawing.Point((int)vedge.Start.X, (int)vedge.Start.Y), new System.Drawing.Point((int)vedge.End.X, (int)vedge.End.Y)); } } } return(ImageSourceFromBitmap(bmp)); }
// "VEdge cont init" /// <summary> /// [BE WARNED: the degraded triangle case, the triangle might degrade into an edge or a point] /// /// /// </summary> private void _InitVEdgeTable() { int[] rvIdxs = m_RealMesh.triangles; int triCnt = rvIdxs.Length / 3; //Dbg.Log("triCnt = {0}", triCnt); //ETimeProf prof = new ETimeProf(); // loop over all real-tris, and generate VEdges for (int triIdx = 0; triIdx < triCnt; triIdx++) { //prof.SecStart(0); int rv0 = rvIdxs[triIdx * 3]; int rv1 = rvIdxs[triIdx * 3 + 1]; int rv2 = rvIdxs[triIdx * 3 + 2]; VVert vv0 = GetVV(rv0); VVert vv1 = GetVV(rv1); VVert vv2 = GetVV(rv2); bool bDegradedTri = (vv0 == vv1) || (vv1 == vv2) || (vv0 == vv2); if (bDegradedTri) { m_DegRTriCont.Add(triIdx); //record the degraded real-tri } //prof.SecEnd(0); if (vv0 != vv1) { VEdge vedge = null; //prof.SecStart(1); if ((vedge = vv0.GetVEdge(vv1)) == null) { vedge = _CreateNewVEdge(vv0, vv1); } Dbg.Assert(vedge != null, "VMesh._InitVEdgeTable: vedge is null"); if (!bDegradedTri) { vedge.AddRTri(triIdx); } //prof.SecEnd(1); } if (vv1 != vv2) { VEdge vedge = null; //prof.SecStart(2); if ((vedge = vv1.GetVEdge(vv2)) == null) { vedge = _CreateNewVEdge(vv1, vv2); } if (!bDegradedTri) { vedge.AddRTri(triIdx); } //prof.SecEnd(2); } if (vv0 != vv2) { VEdge vedge = null; //prof.SecStart(3); if ((vedge = vv2.GetVEdge(vv0)) == null) { vedge = _CreateNewVEdge(vv2, vv0); } if (!bDegradedTri) { vedge.AddRTri(triIdx); } //prof.SecEnd(3); } } // end of for m_VEdgeArr = m_VEdgeCont.ToArray(); //prof.SecShowAll(); }
//combination of personal ray clipping alg and cohen sutherland private static bool ClipEdge(VEdge edge, double minX, double minY, double maxX, double maxY) { var accept = false; //if its a ray if (edge.End == null) { accept = ClipRay(edge, minX, minY, maxX, maxY); } else { //Cohen–Sutherland var start = ComputeOutCode(edge.Start.X, edge.Start.Y, minX, minY, maxX, maxY); var end = ComputeOutCode(edge.End.X, edge.End.Y, minX, minY, maxX, maxY); while (true) { if ((start | end) == 0) { accept = true; break; } if ((start & end) != 0) { break; } double x = -1, y = -1; var outcode = start != 0 ? start : end; if ((outcode & 0x8) != 0) // top { x = edge.Start.X + (edge.End.X - edge.Start.X) * (maxY - edge.Start.Y) / (edge.End.Y - edge.Start.Y); y = maxY; } else if ((outcode & 0x4) != 0) // bottom { x = edge.Start.X + (edge.End.X - edge.Start.X) * (minY - edge.Start.Y) / (edge.End.Y - edge.Start.Y); y = minY; } else if ((outcode & 0x2) != 0) //right { y = edge.Start.Y + (edge.End.Y - edge.Start.Y) * (maxX - edge.Start.X) / (edge.End.X - edge.Start.X); x = maxX; } else if ((outcode & 0x1) != 0) //left { y = edge.Start.Y + (edge.End.Y - edge.Start.Y) * (minX - edge.Start.X) / (edge.End.X - edge.Start.X); x = minX; } if (outcode == start) { edge.Start = new VPoint(x, y); start = ComputeOutCode(x, y, minX, minY, maxX, maxY); } else { edge.End = new VPoint(x, y); end = ComputeOutCode(x, y, minX, minY, maxX, maxY); } } } //if we have a neighbor if (edge.Neighbor != null) { //check it var valid = ClipEdge(edge.Neighbor, minX, minY, maxX, maxY); //both are valid if (accept && valid) { edge.Start = edge.Neighbor.End; } //this edge isn't valid, but the neighbor is //flip and set if (!accept && valid) { edge.Start = edge.Neighbor.End; edge.End = edge.Neighbor.Start; accept = true; } } return(accept); }
public ImageSource GetKingdomMap(string kingdomName) { if (mapPerlin == null) { GenPerlinMap(); } Bitmap bmp = new Bitmap(mapPerlin); Kingdom currentK = this.kingdoms.Where(e => e.Name == kingdomName).First(); using (Graphics g = Graphics.FromImage(bmp)) { List <Point> frontier = new List <Point>(); foreach (Region site in currentK.regions) { List <VEdge> tmp = new List <VEdge>(); int i = 0; tmp.Add(site.Cell.First()); site.Cell.Remove(site.Cell.First()); while (!site.Cell.IsEmpty() && i < site.Cell.Count) { VEdge ve = site.Cell.ElementAt(i); VEdge t = tmp.Last(); if (t.End == ve.Start) { tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else if (t.End == ve.End) { VPoint vp = ve.End; ve.End = ve.Start; ve.Start = vp; tmp.Add(ve); site.Cell.Remove(ve); i = 0; } else { i++; } } site.Cell = tmp; List <Point> points = new List <Point>(); foreach (var edge in site.Cell) { points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y)); points.Add(new Point((int)edge.End.X, (int)edge.End.Y)); } Point[] tab = points.ToArray(); Color color = Color.FromArgb(150, site.Kingdom.Color.R, site.Kingdom.Color.G, site.Kingdom.Color.B); g.FillPolygon(new SolidBrush(color), tab); if (site.City) { if (!site.Capital) { g.FillEllipse(new SolidBrush(Color.White), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } else { g.FillEllipse(new SolidBrush(Color.Yellow), (float)(site.X - 2), (float)(site.Y - 2), 5f, 5f); } } } g.FillRectangle(new SolidBrush(Color.FromArgb(50, 255, 255, 255)), 0, 0, this.mapWidth, this.mapHeight); } return(ImageSourceFromBitmap(bmp)); }
/// <summary> /// This assumes edges are in order. /// </summary> private void CreateNoisyEdges() { if (id == 96) { Debug.Log("paws plx"); } regionBorders = new List <RegionBorder>(); List <VEdge> vEdges = polygon.GetVoronoiEdges(); VEdge currentEdge = vEdges[0]; VEdge lastEdge = vEdges[vEdges.Count - 1]; if (!currentEdge.SharesCorner(lastEdge, out Corner sharedCorner)) { Debug.LogError("Edges are not in order in region " + id); } else { if (sharedCorner != currentEdge.start) { currentEdge.ReverseEndPoints(); } if (sharedCorner != lastEdge.end) { lastEdge.ReverseEndPoints(); } } for (int i = 0; i < vEdges.Count; ++i) { if (i > 0) { currentEdge = vEdges[i]; lastEdge = vEdges[i - 1]; if (!currentEdge.SharesCorner(lastEdge, out sharedCorner)) { Debug.LogError("Edges are not in order in region " + id); } else { if (sharedCorner != currentEdge.start) { currentEdge.ReverseEndPoints(); } if (sharedCorner != lastEdge.end) { lastEdge.ReverseEndPoints(); } } } RegionBorder border = new RegionBorder(currentEdge, Instantiate(borderRenderer, borders)); regionBorders.Add(border); } RegionBorder lastBorder = regionBorders[regionBorders.Count - 1]; RegionBorder firstBorder = regionBorders[0]; if (!lastBorder.edge.SharesCorner(firstBorder.edge, out sharedCorner)) { Debug.LogError("MAJOR ERROR: Edges are not in order in region " + id); } else { if (sharedCorner != lastBorder.edge.end || sharedCorner != firstBorder.edge.start) { Debug.LogError("Last and first edges do not line up in region " + id + " edge " + lastBorder.edge.id); } } }