public CRegion(List<CCell> cells, int mapWidth, int mapHeight) { this.cells = cells; linesMX = new List<CLine>[mapWidth + 1, mapHeight + 1]; linesMXCopy = new List<CLine>[mapWidth + 1, mapHeight + 1]; cells.ForEach((c) => { c.lines.ForEach((l) => { if (linesMX[l.x1, l.y1] == null) { linesMX[l.x1, l.y1] = new List<CLine>(); linesMX[l.x1, l.y1].Add(l); linesMXCopy[l.x1, l.y1] = new List<CLine>(); linesMXCopy[l.x1, l.y1].Add(l); } else { linesMX[l.x1, l.y1].Add(l); linesMXCopy[l.x1, l.y1].Add(l); } if (firstLine == null) { firstLine = l; linesMX[l.x1, l.y1] = null; } }); }); }
private void DefineRay(CLine l1, CLine l2) { //Debug.Log(l1 + " " + l1.sideType + " / " + l2 + " " + l2.sideType); if (forward) DefineRay(l1.sideType, l1.GetCornerType(l2)); else DefineRay(l2.sideType, l2.GetCornerType(l1)); }
internal CRayQualifier(CLine firstLine, CLine endLine, bool forwardDirection, bool insideCast = true) { forward = forwardDirection; DefineRay(firstLine, endLine); lastLine = firstLine; inCast = insideCast; }
private void BuildEntirePolygon(CLine entranceLine, CLine joinLine = null) { var poly = entranceLine.container; passedPolys.Add(poly); int n = poly.lines.FindIndex((line) => { return line == entranceLine; }); //Long :( need Dictionary! int previousN = n > 0 ? n - 1 : poly.lines.Count - 1; bool insideCast = poly.depth == 0; CLine l = entranceLine; CRayQualifier qualifier = new CRayQualifier(entranceLine, poly.lines[previousN], true, insideCast); bool needMorePolygons = true; while (needMorePolygons) { finalLines.Add(new CLine(l.NPoints[0], l.NPoints[1])); var rays = qualifier.GetRay(); CLine foundLine = null; if (rays[0] != 0) foundLine = HorizontalCast(l.x1, l.y1, rays[0]); if (rays[1] != 0) foundLine = VerticalCast(l.x1, l.y1, rays[1]); if (foundLine != null && !passedPolys.Contains(foundLine.container)) { finalLines.Add(new CLine(l.NPoints[0], foundLine.NPoints[0], true)); BuildEntirePolygon(foundLine, finalLines.Last()); n = n - 1 >= 0 ? n - 1 : poly.lines.Count - 1; } if (l.NPoints[1] == entranceLine.NPoints[0]) { needMorePolygons = false; if (joinLine != null) finalLines.Add(new CLine(joinLine.NPoints[1], joinLine.NPoints[0], true)); } else { n = n + 1 < poly.lines.Count ? n + 1 : 0; l = poly.lines[n]; qualifier.NextStep(l); } } }
public virtual CornerType GetCornerType(CLine line) { if (this.sideType == line.sideType) return CornerType.None; CLine l1 = line; CLine l2 = this; if ((l1.sideType == ST.Left && l2.sideType == ST.Top) || (l1.sideType == ST.Down && l2.sideType == ST.Left) || (l1.sideType == ST.Right && l2.sideType == ST.Down) || (line.sideType == ST.Top && l2.sideType == ST.Right)) return CornerType.Open; return CornerType.Closed; }
public virtual bool IsOrthogonal(CLine line) { return x1 != line.x2 && y2 == line.y1; }
internal void NextStep(CLine l) { DefineRay(l, lastLine); lastLine = l; }
private void PreBuildPolygon(CLine fl) { var lines = new List<CLine>(); Vector2[] mp = { new Vector2(fl.x1, fl.y1), new Vector2(fl.x2, fl.y2) }; var polygon = new CPolygon(mp, lines); int diagonals = 0; while (fl != null) { lines.Add(fl); fl.container = polygon; foreach (var p in fl.NPoints) { if (mp[0].x > p.x) mp[0].x = p.x; if (mp[0].y > p.y) mp[0].y = p.y; if (mp[1].x < p.x) mp[1].x = p.x; if (mp[1].y < p.y) mp[1].y = p.y; } var nl = linesMX[fl.x2, fl.y2]; if (nl != null && nl.Count != 0) { if (nl.Count == 1) { fl = nl[0]; linesMX[fl.x1, fl.y1] = null; } else { diagonals++; if (fl.IsOrthogonal(nl[0])) { fl = nl[0]; nl.RemoveAt(0); } else { fl = nl[1]; nl.RemoveAt(1); } } } else fl = null; } polygon.diagonals = diagonals; polygon.Recalculate(); polys.Add(polygon); }
private void PreBuilding() { while (firstLine != null) { PreBuildPolygon(firstLine); firstLine = null; foreach (var l in linesMX) if (l != null) { firstLine = l[0]; break; } } }