void Reset() { PhysicsSimulator.Game = game; sim = new PhysicsSimulator(); sim.Gravity *= 2.0f; lb = new LineBrush(game.GraphicsDevice, 1); poly = new Polygon(); poly.AddVertex(0, 0); poly.AddVertex(0, 150); poly.AddVertex(100, 150); poly.AddVertex(100, 0);/* * poly.AddVertex(50, 100); * poly.AddVertex(50, 50); * poly.AddVertex(100, 50); * poly.AddVertex(100, 0);*/ poly.Triangulate(); var poly2 = new Polygon(); poly2.AddVertex(0, 500); poly2.AddVertex(500, 400); poly2.AddVertex(800, 500); poly2.AddVertex(800, 600); poly2.AddVertex(0, 600); poly2.Triangulate(); var poly3 = new Polygon(); poly3.AddVertex(700, 0); poly3.AddVertex(800, 0); poly3.AddVertex(800, 450); poly3.AddVertex(700, 450); poly3.Triangulate(); var circle = Polygon.BuildCircle(20, new Vector2(600), 90); circle.Triangulate(); bodies = new List <Body>(); bodies.Add(new Body(sim, game, poly, 10)); bodies.Add(new Body(sim, game, poly2, 10)); bodies.Add(new Body(sim, game, poly3, 10)); bodies.Add(new Body(sim, game, circle, 10)); //body1.AttachToGravity = false; bodies[1].IsStatic = true; bodies[2].IsStatic = true; bodies[3].IsStatic = true; //body2.IsFree = true; palette = new List <Color>(); for (int i = 0; i < 10; i++) { palette.Add(GraphicsHelper.GetRandomColor()); } }
void Reset() { poly1 = Polygon.BuildCircle(20, new Vector2(10), 70); poly1.AutoTriangulate = true; poly1.Triangulate(); poly2 = new Polygon(); poly2.AddVertex(0, 500); poly2.AddVertex(800, 500); poly2.AddVertex(800, 600); poly2.AddVertex(0, 600); poly2.Vertices = poly2.GetVerticesCounterClockwise(); poly2.AutoTriangulate = true; poly2.Triangulate(); }
public static void OpenInputData(StreamReader sr, out Polygon polygon, out Model model, out Boundary boundary) { int countNodes = int.Parse(sr.ReadLine()); polygon = new Polygon(); for (int i = 0; i < countNodes; i++) { polygon.AddVertex(Node.Parse(sr.ReadLine())); } model = new Model(); string k = sr.ReadLine(); string[] kItems = k.Split(); model.K[0, 0] = double.Parse(kItems[0]); model.K[0, 1] = double.Parse(kItems[1]); model.K[1, 0] = double.Parse(kItems[2]); model.K[1, 1] = double.Parse(kItems[3]); model.D = double.Parse(sr.ReadLine()); model.F = double.Parse(sr.ReadLine()); List <BoundaryCharacteristic> listBoundaryCharacteristic = new List <BoundaryCharacteristic>(); for (int i = 0; i < countNodes; i++) { listBoundaryCharacteristic.Add(BoundaryCharacteristic.Parse(sr.ReadLine())); } boundary = new Boundary(listBoundaryCharacteristic.ToArray()); }
public static Polygon Union(Canvas canvas, Polygon window, Polygon subject) { Point startPoint; POLYGON startPolygon; FindAndOrderPoints(window, subject, out startPoint, out startPolygon); if (startPoint.X == int.MaxValue) { return(window.minX < subject.minX ? window : subject); } Point currentPoint = startPoint; POLYGON currentPolygon = startPolygon; Polygon polygon = new Polygon(canvas); do { polygon.AddVertex(currentPoint.X, currentPoint.Y); if (currentPolygon == POLYGON.WINDOW) { currentPolygon = currentPoint.CrossPoint ? POLYGON.SUBJECT : POLYGON.WINDOW; currentPoint = currentPoint.CrossPoint ? currentPoint.SubjectNext : currentPoint.WindowNext; } else { currentPolygon = currentPoint.CrossPoint ? POLYGON.WINDOW : POLYGON.SUBJECT; currentPoint = currentPoint.CrossPoint ? currentPoint.WindowNext : currentPoint.SubjectNext; } } while (currentPoint != startPoint); //end do while there are more points polygon.ClosePolygon(); return(polygon); }
static void Main(string[] args) { Polygon lp = new Polygon(); lp.AddVertex(new Node(0, 0)); lp.AddVertex(new Node(1, 0)); lp.AddVertex(new Node(1, 1)); lp.AddVertex(new Node(0, 1)); GeneratingMesh gener = new GeneratingMesh(lp, 2); gener.eps = 0.001; Mesh m = gener.GenerateGrid(); /* * Segment s1 = new Segment(new Point(0, 0), new Point(1, 0)); * Segment s2 = new Segment(new Point(1, 0), new Point(1, 1)); * * Console.WriteLine(Segment.angle(s1,s2));*/ }
private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { if (mode == ProgramMode.DrawMode) { Point point = new Point(e.X, e.Y); Node node = GraphicFunctions.ConvertToOwn(point); polygon.AddVertex(node); GraphicFunctions.DrawNode(node, g, false, 0); pictureBox1.Image = btm; } }
void LoadMap() { NewWorld(); try { StreamReader sr = new StreamReader(filename); while (!sr.EndOfStream) { string data = sr.ReadLine().Trim(); if (data == "~object") { currentObject = new GameObject(); currentObject.name = sr.ReadLine().Trim(); currentObject.texture = sr.ReadLine().Trim(); Polygon p = new Polygon(); var vertexdata = sr.ReadLine().Trim(); string vs = ""; for (int i = 0; i < vertexdata.Length; i++) { if (vertexdata[i] == ' ') { p.AddVertex(Neat.Mathematics.GeometryHelper.String2Vector(vs)); vs = ""; } else { vs += vertexdata[i]; } } currentObject.speed = Vector.FromString(sr.ReadLine()); currentObject.body.IsFree = bool.Parse(sr.ReadLine()); currentObject.body.Pushable = bool.Parse(sr.ReadLine()); currentObject.body.AttachToGravity = bool.Parse(sr.ReadLine()); currentObject.body.Mass = float.Parse(sr.ReadLine()); objects.Add(currentObject); } else if (data == "~script") { textBox1.Text = sr.ReadToEnd(); } else { MessageBox.Show("File is damaged."); return; } } sr.Close(); RefreshObjectsList(); } catch (Exception) { throw; } }
public void AddVertexThrowsExceptionWhenAddingDuplicateNode() { PointGeo p1 = new PointGeo(1.0, 1.0); PointGeo p2 = new PointGeo(2.0, 1.0); PointGeo p3 = new PointGeo(2.0, 2.0); PointGeo p4 = new PointGeo(1.0, 2.0); List<IPointGeo> nodes = new List<IPointGeo>(new IPointGeo[] { p1, p2, p3, p4 }); Polygon<PointGeo> target = new Polygon<PointGeo>(nodes); Assert.Throws<ArgumentException>(delegate { target.AddVertex(p2); }); }
public PolygonViewModel() { firstInputHandler = new EditorInputHandler(firstPolygon); secondInputHandler = new CreationInputHandler(secondPolygon); firstPolygon.AddVertex(100, 100); firstPolygon.AddVertex(300, 50); firstPolygon.AddVertex(500, 280); firstPolygon.AddVertex(800, 300); firstPolygon.AddVertex(400, 500); firstPolygon.AddVertex(50, 300); secondPolygon.AddVertex(130, 80); secondPolygon.AddVertex(200, 10); secondPolygon.AddVertex(800, 600); secondPolygon.AddVertex(100, 200); firstPolygon.SetClosed(); secondPolygon.SetClosed(); firstPolygonFiller = new PolygonFiller(firstPolygon); firstPolygonFiller.SetSettings(Filling.GetFillingSettings()); }
public void PolygonAddVertexAddsVertexToTheEnd() { PointGeo p1 = new PointGeo(1.0, 1.0); PointGeo p2 = new PointGeo(2.0, 1.0); PointGeo p3 = new PointGeo(2.0, 2.0); PointGeo p4 = new PointGeo(1.0, 2.0); List<IPointGeo> nodes = new List<IPointGeo>(new IPointGeo[] { p1, p2, p3}); Polygon<PointGeo> target = new Polygon<PointGeo>(nodes); target.AddVertex(p4); nodes.Add(p4); CompareVerticesLists(nodes, target.Vertices); }
private void OnValidate() { var seq = RandomBaryCentricSequence(3); Debug.Log(seq[0] + seq[1] + seq[2]); _poly = new Polygon(); _poly2 = new Polygon(); for (int i = 0; i < _sides; i++) { _poly.Vertices.Add(UnityEngine.Random.insideUnitCircle); _poly2.Vertices.Add(new Vector2(10, 0) + UnityEngine.Random.insideUnitCircle); } _poly.Order(); _poly2.Order(); _polyInside = new Polygon(); for (int i = 0; i < _sides; i++) { var barycentrics = RandomBaryCentricSequence(_sides); Vector2 vert = BaryToVec(_poly, barycentrics); _polyInside.AddVertex(vert); } _polyInside.Order(); // _polyInside2 = new Polygon(); // for (int i = 0; i < _sides; i++) // { // var barycentrics = RandomBaryCentricSequence(_sides); // Vector2 vert = BaryToVec(_poly2, barycentrics); // _polyInside2.AddVertex(vert); // } // _polyInside2.Order(); }
/// <summary> /// Computes edges and creates polygons from those connected by vertices. /// </summary> public void BuildPolygons() { var computedVertices = new List <Vertex>(); foreach (Vertex v in vertices) { // If already belongs to a polygon or is not a polygon vertex or already computed if (computedVertices.Contains(v) || graph[v].Count > 2) { continue; } computedVertices.Add(v); Polygon polygon = new Polygon(GetNextId(), false); polygon.AddVertex(v); foreach (Edge edge in GetVertexEdges(v)) { Edge currentEdge = edge; Vertex currentVertex = edge.GetVertexPair(v); while (!polygon.vertices.Contains(currentVertex) || !computedVertices.Contains(currentVertex)) { polygon.AddVertex(currentVertex); polygon.edges.Add(currentEdge); var connectedEdges = graph[currentVertex]; //It is extreme vertex, polygon not closed if (connectedEdges.Count < 2) { break; } // If just two edges, select the one that is not current nextEdge else if (connectedEdges.Count == 2) { currentEdge = connectedEdges[0].Equals(currentEdge) ? connectedEdges[1] : connectedEdges[0]; } // If 4, is self intersection else if (connectedEdges.Count == 4) { var edgesWithVertexAlreadyInPolygon = connectedEdges .Where(e => !e.Equals(currentEdge) && polygon.Vertices.Contains(e.GetVertexPair(currentVertex))) .ToList(); //If any of them connects to a vertex already on the current polygon, // If only one, set as current and it will close the polygon on the next iteration if (edgesWithVertexAlreadyInPolygon.Count == 1) { currentEdge = edgesWithVertexAlreadyInPolygon.First(); } // If two, it means that is a intersection with two previous edges computed, // so set the next to the one that is not parallel to current else if (edgesWithVertexAlreadyInPolygon.Count == 2) { currentEdge = edgesWithVertexAlreadyInPolygon[0].Direction.IsParallelTo(currentEdge.Direction) ? edgesWithVertexAlreadyInPolygon[1] : edgesWithVertexAlreadyInPolygon[0]; } // More than two, none on the current polygon so select one of those not yet computed else { polygon.edges.Reverse(); polygon.Vertices.Reverse(); break; //it will go the other way around } } else { throw new Exception("WARNING. Something unexepected happend with the polygons..."); } computedVertices.Add(currentVertex); currentVertex = currentEdge.GetVertexPair(currentVertex); } if (!polygon.edges.Last().Equals(currentEdge)) { polygon.edges.Add(currentEdge); } } this.polygons.Add(polygon.id, polygon); } }
public static void AddWays(this Polygon <OSMNode> polygon, IList <OSMWay> ways, OSMDB db) { if (ways.Count == 1) { // Check if the created polygon is closed if (ways[0].Nodes.Count > 0 && ways[0].Nodes.First() != ways[0].Nodes.Last()) { throw new ArgumentException("Ways does not form a closed polygon"); } for (int i = 0; i < ways[0].Nodes.Count - 1; i++) { polygon.AddVertex(db.Nodes[ways[0].Nodes[i]]); } } else { long lastVertexID = 0; if (ways[0].Nodes.First() == ways.Last().Nodes.First() || ways[0].Nodes.Last() == ways.Last().Nodes.First()) { lastVertexID = ways.Last().Nodes.First(); } else { lastVertexID = ways.Last().Nodes.Last(); } //// Check orientation of the first way //if (ways[0].Nodes.First() == ways[1].Nodes.First() || ways[0].Nodes.First() == ways[1].Nodes.First()) { // for (int ii = ways[0].; ii < verticesToAdd.Count - 1; ii++) { // AddVertex(verticesToAdd[ii]); // } //} for (int i = 0; i < ways.Count; i++) { List <long> verticesToAdd = new List <long>(); // Checks the way orienatation and picks nodes in correct order if (lastVertexID == ways[i].Nodes[0]) { verticesToAdd.AddRange(ways[i].Nodes); } else if (lastVertexID == ways[i].Nodes.Last()) { verticesToAdd.AddRange(ways[i].Nodes.Reverse()); } else { throw new ArgumentException("Can not create polygon, ways aren't connected"); } for (int ii = 0; ii < verticesToAdd.Count - 1; ii++) { polygon.AddVertex(db.Nodes[verticesToAdd[ii]]); } lastVertexID = verticesToAdd.Last(); } // Check if the created polygon is closed if (polygon.VerticesCount > 0 && polygon.Vertices.First() != db.Nodes[lastVertexID]) { throw new ArgumentException("Ways does not form a closed polygon"); } } }
/** * @brief 提取数据 * * @param node * * @return */ public bool CollectDataFromDBC(DBC_Row node) { m_Id = DBCUtil.ExtractNumeric <int>(node, "Id", 0, true); m_Name = DBCUtil.ExtractString(node, "Name", "", true); m_ShowName = DBCUtil.ExtractBool(node, "ShowName", false, false); m_NpcType = DBCUtil.ExtractNumeric <int>(node, "NpcType", 0, true); m_NpcFigure = DBCUtil.ExtractNumeric <int>(node, "NpcFigure", 0, false); m_Level = DBCUtil.ExtractNumeric <int>(node, "Level", 0, true); m_Scale = DBCUtil.ExtractNumeric <float>(node, "Scale", 1.0f, false); m_ParticleScale = DBCUtil.ExtractNumeric <float>(node, "ParticleScale", 1.0f, false); m_Portrait = DBCUtil.ExtractString(node, "Portrait", "", false); m_AttrData.CollectDataFromDBC(node); m_CauseStiff = DBCUtil.ExtractBool(node, "CauseStiff", true, false); m_AcceptStiff = DBCUtil.ExtractBool(node, "AcceptStiff", true, false); m_AcceptStiffEffect = DBCUtil.ExtractBool(node, "AcceptStiffEffect", true, false); //m_SuperArmor = DBCUtil.ExtractNumeric<bool>(node, "SuperArmor", false, false); m_ViewRange = DBCUtil.ExtractNumeric <float>(node, "ViewRange", -1, true); m_GohomeRange = DBCUtil.ExtractNumeric <float>(node, "GohomeRange", -1, true); m_ReleaseTime = DBCUtil.ExtractNumeric <long>(node, "ReleaseTime", 0, true); m_SkillList = DBCUtil.ExtractNumericList <int>(node, "SkillList", 0, false); m_DeadSkill = DBCUtil.ExtractNumeric <int>(node, "DeadSkill", -1, false); m_ActionList = DBCUtil.ExtractNumericList <int>(node, "ActionId", 0, false); m_Model = DBCUtil.ExtractString(node, "Model", "", false); m_BornEffect = DBCUtil.ExtractString(node, "BornEffect", "", false); m_BornEffectTime = DBCUtil.ExtractNumeric <float>(node, "BornEffectTime", -1, false); m_MeetEnemyImpact = DBCUtil.ExtractNumeric <int>(node, "MeetEnemyImpact", 0, false); m_BornAnimTime = DBCUtil.ExtractNumeric <int>(node, "BornAnimTime", 400, false); m_AvoidanceRadius = DBCUtil.ExtractNumeric <int>(node, "AvoidanceRadius", 1, false); m_CanMove = DBCUtil.ExtractBool(node, "CanMove", false, false); m_CanHitMove = DBCUtil.ExtractBool(node, "CanHitMove", true, false); m_CanRotate = DBCUtil.ExtractBool(node, "CanRotate", true, false); m_IsAttachControler = DBCUtil.ExtractBool(node, "IsAttachControler", false, false); m_AttachNodeName = DBCUtil.ExtractString(node, "AttachNodeName", "", false); m_Cross2StandTime = DBCUtil.ExtractNumeric <float>(node, "Cross2StandTime", 0.5f, false); m_Cross2Runtime = DBCUtil.ExtractNumeric <float>(node, "Cross2RunTime", 0.3f, false); m_DeadAnimTime = DBCUtil.ExtractNumeric <float>(node, "DeadAnimTime", 1.4f, false); m_TauntSound = Converter.ConvertStringList(DBCUtil.ExtractString(node, "TauntSound", "", false)); m_HitSounds = Converter.ConvertStringList(DBCUtil.ExtractString(node, "HitSound", "", false)); m_DeadSound = Converter.ConvertStringList(DBCUtil.ExtractString(node, "DeadSound", "", false)); string shapeType = DBCUtil.ExtractString(node, "ShapeType", "", true); int shapeParamNum = DBCUtil.ExtractNumeric <int>(node, "ShapeParamNum", 0, true); if (shapeParamNum > 0) { string[] shapeParams = new string[shapeParamNum]; for (int i = 0; i < shapeParamNum; ++i) { shapeParams[i] = DBCUtil.ExtractString(node, "ShapeParam" + i, "", false); } if (0 == string.Compare("Circle", shapeType, true)) { m_Shape = new Circle(new Vector3(0, 0, 0), float.Parse(shapeParams[0])); } else if (0 == string.Compare("Line", shapeType, true)) { Vector3 start = Converter.ConvertVector3D(shapeParams[0]); Vector3 end = Converter.ConvertVector3D(shapeParams[1]); m_Shape = new Line(start, end); } else if (0 == string.Compare("Rect", shapeType, true)) { float width = float.Parse(shapeParams[0]); float height = float.Parse(shapeParams[1]); m_Shape = new ArkCrossEngineSpatial.Rect(width, height); } else if (0 == string.Compare("Polygon", shapeType, true)) { Polygon polygon = new Polygon(); foreach (string s in shapeParams) { Vector3 pt = Converter.ConvertVector3D(s); polygon.AddVertex(pt); } m_Shape = polygon; } } return(true); }
public static Polygon GetIntersectedPolygon(Polygon subjectPolygon, Polygon clipPolygon) { var subjectPolygonTmp = subjectPolygon; if (!clipPolygon.IsConvex()) { subjectPolygon = clipPolygon; clipPolygon = subjectPolygonTmp; } if (!clipPolygon.IsConvex()) { return(clipPolygon); } List <Vertex> output = new List <Vertex>(subjectPolygon.GetVertexes()); foreach (var edge in clipPolygon.GetEdges()) { List <Vertex> input = output; output = new List <Vertex>(); if (!input.Any()) { return(subjectPolygonTmp); } Vertex pp = input[input.Count - 1]; foreach (var p in input) { if (IsInnerPoint(p, clipPolygon.GetVertexes().ToArray(), edge)) { if (!IsInnerPoint(pp, clipPolygon.GetVertexes().ToArray(), edge)) { output.Add(GetIntersectionPoint((p, pp), edge)); } output.Add(p); } else if (IsInnerPoint(pp, clipPolygon.GetVertexes().ToArray(), edge)) { output.Add(GetIntersectionPoint((p, pp), edge)); } pp = p; } } for (int i = 0; i < output.Count - 1; i++) { if (output[i] == output[i + 1]) { output.RemoveAt(i--); } } Polygon intersectedPolygon = new Polygon(); foreach (var vertex in output) { intersectedPolygon.AddVertex(vertex.X, vertex.Y); } intersectedPolygon.SetClosed(); return(intersectedPolygon.GetVertexes().Any() ? intersectedPolygon : subjectPolygonTmp); }
/** * @brief 提取数据 * * @param node * * @return */ public bool CollectDataFromDBC(DBC_Row node) { m_Id = DBCUtil.ExtractNumeric <int>(node, "Id", 0, true); m_Name = DBCUtil.ExtractString(node, "Name", "", true); m_NpcType = DBCUtil.ExtractNumeric <int>(node, "NpcType", 0, true); m_Level = DBCUtil.ExtractNumeric <int>(node, "Level", 0, true); m_Scale = DBCUtil.ExtractNumeric <float>(node, "Scale", 1.0f, true); m_DropCount = DBCUtil.ExtractNumeric <int>(node, "DropCount", 0, false); m_DropExp = DBCUtil.ExtractNumeric <int>(node, "DropExp", 0, false); m_DropMoney = DBCUtil.ExtractNumeric <int>(node, "DropMoney", 0, false); List <int> list = DBCUtil.ExtractNumericList <int>(node, "DropProbabilities", 0, false); if (list.Count > 0) { m_DropProbabilities = list.ToArray(); } list = DBCUtil.ExtractNumericList <int>(node, "DropNpcs", 0, false); if (list.Count > 0) { m_DropNpcs = list.ToArray(); } list = DBCUtil.ExtractNumericList <int>(node, "InteractSourceActions", 0, false); if (list.Count > 0) { m_InteractSourceActions = list.ToArray(); } else { m_InteractSourceActions = new int[] { 0, 0 }; } list = DBCUtil.ExtractNumericList <int>(node, "InteractTargetActions", 0, false); if (list.Count > 0) { m_InteractTargetActions = list.ToArray(); } else { m_InteractTargetActions = new int[] { 0, 0 }; } m_InteractionLogic = DBCUtil.ExtractNumeric <int>(node, "InteractionLogic", 0, false); List <string> strList = DBCUtil.ExtractStringList(node, "InteractResultData", "", false); if (strList.Count > 0) { m_InteractResultData = strList.ToArray(); } m_AttrData.CollectDataFromDBC(node); m_ViewRange = DBCUtil.ExtractNumeric <float>(node, "ViewRange", -1, true); m_GohomeRange = DBCUtil.ExtractNumeric <float>(node, "GohomeRange", -1, true); m_ReleaseTime = DBCUtil.ExtractNumeric <long>(node, "ReleaseTime", 0, true); m_HeadUiPos = DBCUtil.ExtractNumeric <int>(node, "HeadUiPos", 0, true); m_SkillList = DBCUtil.ExtractNumericList <int>(node, "SkillList", 0, false); m_ActionList = DBCUtil.ExtractNumericList <int>(node, "ActionId", 0, false); m_Model = DBCUtil.ExtractString(node, "Model", "", false); m_DeathModel = DBCUtil.ExtractString(node, "DeathModel", "", false); m_DeathEffect = DBCUtil.ExtractString(node, "DeathEffect", "", false); m_DeathSound = DBCUtil.ExtractString(node, "DeathSound", "", false); m_DeadType = DBCUtil.ExtractNumeric <int>(node, "DeadType", 0, false); m_Barrage = DBCUtil.ExtractNumeric <int>(node, "Barrage", 0, false); m_AvoidanceRadius = DBCUtil.ExtractNumeric <int>(node, "AvoidanceRadius", 1, false); m_CanMove = DBCUtil.ExtractBool(node, "CanMove", false, false); m_CanRotate = DBCUtil.ExtractBool(node, "CanRotate", true, false); m_IsRange = DBCUtil.ExtractBool(node, "IsRange", false, false); m_IsShine = DBCUtil.ExtractBool(node, "IsShine", false, false); m_isBlaze = DBCUtil.ExtractBool(node, "IsBlaze", false, false); m_IsHurtComa = DBCUtil.ExtractBool(node, "IsHurtComa", false, false); m_BornTimeMs = DBCUtil.ExtractNumeric <int>(node, "BornTimeMs", 0, false); m_BornEffect = DBCUtil.ExtractString(node, "BornEffect", "", false); m_IsAttachControler = DBCUtil.ExtractBool(node, "IsAttachControler", false, false); m_AttachNodeName = DBCUtil.ExtractString(node, "AttachNodeName", "", false); m_GunEndRelativePos = Converter.ConvertVector3D(DBCUtil.ExtractString(node, "GunEndRelativePos", "0.0,0.0,0.0", false)); m_WeaponList = DBCUtil.ExtractNumericList <int>(node, "WeaponId", 0, false); string shapeType = DBCUtil.ExtractString(node, "ShapeType", "", true); int shapeParamNum = DBCUtil.ExtractNumeric <int>(node, "ShapeParamNum", 0, true); if (shapeParamNum > 0) { string[] shapeParams = new string[shapeParamNum]; for (int i = 0; i < shapeParamNum; ++i) { shapeParams[i] = DBCUtil.ExtractString(node, "ShapeParam" + i, "", false); } if (0 == string.Compare("Circle", shapeType, true)) { m_Shape = new Circle(new Vector3(0, 0, 0), float.Parse(shapeParams[0])); } else if (0 == string.Compare("Line", shapeType, true)) { Vector3 start = Converter.ConvertVector3D(shapeParams[0]); Vector3 end = Converter.ConvertVector3D(shapeParams[1]); m_Shape = new Line(start, end); } else if (0 == string.Compare("Rect", shapeType, true)) { float width = float.Parse(shapeParams[0]); float height = float.Parse(shapeParams[1]); m_Shape = new Rect(width, height); } else if (0 == string.Compare("Polygon", shapeType, true)) { Polygon polygon = new Polygon(); foreach (string s in shapeParams) { Vector3 pt = Converter.ConvertVector3D(s); polygon.AddVertex(pt); } m_Shape = polygon; } } return(true); }
/// <summary> /// Generates polygons and nodegraphs using custom algorithm /// </summary> /// <param name="points"></param> /// <param name="pointWidth"></param> /// <param name="pointHeight"></param> private void GenerateVoronoi(List <Vector2> points, int pointWidth, int pointHeight) { var startTime = DateTime.Now; Polygons = new List <Polygon>(); _voronoiVertices = new List <VoronoiVertex>(); // assigns the max width and height of the "grid" of points used SetGraphLimits(pointWidth, pointHeight); List <Node <Polygon> > nodes = new List <Node <Polygon> >(); // generate an empty node for each polygon foreach (var point in points) { nodes.Add(new Node <Polygon>(new Polygon() { Centre = point })); } // go trough all "sites" for (int pointIndex = 0; pointIndex < points.Count; pointIndex++) { Polygon poly = nodes[pointIndex].Data; int mapX, mapY; // grid position of the polygon mapX = pointIndex % pointWidth; mapY = pointIndex / pointHeight; // the grid point surrounding the current point List <int> surroundingPoints = GetSurrouding(mapX, mapY); // check all the surrounding grid points in sets of 3 for (int point0i = 0; point0i < surroundingPoints.Count; point0i++) { for (int point1i = 0; point1i < surroundingPoints.Count; point1i++) { if (point0i == point1i) { continue; } // we skip polygons with more vertices than our limit if (poly.Vertices.Count > _maxPolyVertices) { // "double break" goto end; } Vector2 vertex; // does a circumcircle check if (CheckCircle(pointIndex, surroundingPoints[point0i], surroundingPoints[point1i], ref surroundingPoints, ref points, out vertex)) { // our vertex indicates a shared edge with two other sites, add them to the nodegraph connections float angle = Mathf.Atan2(vertex.y - poly.Centre.y, vertex.x - poly.Centre.x) * Mathf.Rad2Deg + 180f; if (!nodes[pointIndex].ConnectionAngles.ContainsKey(angle)) { if (!nodes[pointIndex].ConnectionAngles.ContainsValue(nodes[surroundingPoints[point0i]])) { nodes[pointIndex].ConnectionAngles.Add(angle, nodes[surroundingPoints[point0i]]); } else { nodes[pointIndex].ConnectionAngles.Add(angle, nodes[surroundingPoints[point1i]]); } } // our vertex is added to the polygon poly.AddVertex(vertex); } } } end: // orders the vertices of the polygon clockwise poly.Order(); poly.Node = nodes[pointIndex]; Polygons.Add(poly); } // ensures there are no double connections in the nodelist _polygons = _polygons.Distinct().ToList(); // sort node angles nodes.ForEach((node) => node.ConnectionAngles = node.ConnectionAngles.OrderBy(a => a.Key).ToDictionary(x => x.Key, x => x.Value)); // removes OOB polygons var oobPolies = _polygons.Where( (Polygon p) => !p.Vertices.TrueForAll((Vector2 vert) => _pointMap.InBound(vert)) ); oobPolies.ToList().ForEach((poly) => { poly.Node.ConnectionAngles.Values.ToList().ForEach( (connectedPoly) => { float key = connectedPoly.ConnectionAngles.FirstOrDefault(x => x.Value.Data.Centre == poly.Centre).Key; connectedPoly.ConnectionAngles.Remove(key); } ); }); _polygons = _polygons.Except(oobPolies).ToList(); // arbitrary start to our nodegraph _nodeGraph = nodes[0]; }
/// <summary> /// Splits a polygon by a given plane, resulting in two polygons. Note /// that this function assumes that the polygon intersects the split plane. /// </summary> /// <param name="poly"></param> /// <param name="splitPlane"></param> /// <returns>Two polygons in a list.</returns> public static List <Polygon> SplitPolygon(Polygon poly, Plane splitPlane) { Polygon front = new Polygon(); Polygon back = new Polygon(); front.Used = poly.Used; front.Plane = poly.Plane; back.Used = poly.Used; back.Plane = poly.Plane; Vector3 pointA, pointB; PointClassification sideA, sideB; pointA = poly.Vertices.Last(); sideA = ClassifyPoint(pointA, splitPlane); for (int i = 0; i < poly.Vertices.Count; i++) { pointB = poly.Vertex(i); sideB = ClassifyPoint(pointB, splitPlane); if (sideB == PointClassification.Front) { if (sideA == PointClassification.Back) { Vector3 v = (pointB - pointA).normalized; Ray r = new Ray(pointA, v); float e; splitPlane.Raycast(r, out e); Vector3 intersectionPoint = pointA + v * e; front.AddVertex(intersectionPoint); back.AddVertex(intersectionPoint); } front.AddVertex(pointB); } else if (sideB == PointClassification.Back) { if (sideA == PointClassification.Front) { Vector3 v = (pointB - pointA).normalized; Ray r = new Ray(pointA, v); float e; splitPlane.Raycast(r, out e); Vector3 intersectionPoint = pointA + v * e; front.AddVertex(intersectionPoint); back.AddVertex(intersectionPoint); } back.AddVertex(pointB); } else { front.AddVertex(pointB); back.AddVertex(pointB); } pointA = pointB; sideA = sideB; } return(new List <Polygon>() { front, back }); }