public MyPolygon CopyWithoutDrawing() { List <MyPoint> verticleList = new List <MyPoint>(); MyPolygon p = new MyPolygon(); p.Edges = new List <MyEdge>(); //add to verticleList foreach (var edge in Edges) { verticleList.Add(edge.first.CopyWithoutDrawing()); } //create edges list from verticleList for (int i = 0; i < verticleList.Count; i++) { var edge = new MyEdge(verticleList[i], verticleList[(i + 1) % verticleList.Count]); p.Edges.Add(edge); } //copying relations for (int i = 0; i < Edges.Count; i++) { p.Edges[i].relationType = Edges[i].relationType; if (Edges[i].relationType != RelationType.None) { var index = Edges.FindIndex(x => Object.ReferenceEquals(x, Edges[i].relationEdge) == true); p.Edges[i].relationEdge = p.Edges[index]; } } return(p); }
public static bool DoIntersect(MyEdge e1, MyEdge e2) { var d1 = MyPoint.VectorProduct((e2.second - e2.first), (e1.first - e2.first)); var d2 = MyPoint.VectorProduct((e2.second - e2.first), (e1.second - e2.first)); var d3 = MyPoint.VectorProduct((e1.second - e1.first), (e2.first - e1.first)); var d4 = MyPoint.VectorProduct((e1.second - e1.first), (e2.second - e1.first)); var d12 = d1 * d2; var d34 = d3 * d4; if (d12 > 0 || d34 > 0) { return(false); } if (d12 < 0 || d34 < 0) { return(true); } return(MyPoint.OnRectangle(e1.first, e2.first, e2.second) || MyPoint.OnRectangle(e1.second, e2.first, e2.second) || MyPoint.OnRectangle(e2.first, e1.first, e1.second) || MyPoint.OnRectangle(e2.second, e1.first, e1.second)); }
public static void Edge(MyEdge edge, Canvas canvas) { switch (Globals.lineDrawingMode) { case LineDrawingMode.Bresenham: MyLine myLine1 = new MyLine(canvas); myLine1.firstPoint = new Point(edge.first.X, edge.first.Y); myLine1.secondPoint = new Point(edge.second.X, edge.second.Y); edge.myLine = myLine1; //algorytm Bresenhama myLine1.DrawBresenhamLine(Globals.DefaultEdgeColor); break; case LineDrawingMode.Library: MyLine myLine2 = new MyLine(canvas); Line line2 = new Line() { X1 = edge.first.X, Y1 = edge.first.Y, X2 = edge.second.X, Y2 = edge.second.Y, StrokeThickness = Globals.LineThickness, Stroke = new SolidColorBrush(Globals.DefaultEdgeColor) }; Panel.SetZIndex(line2, Globals.LineZIndex); canvas.Children.Add(line2); //myLine = new MyLine(canvas); myLine2.lineWindowsControl = line2; //myLine.canvas = canvas; edge.myLine = myLine2; break; case LineDrawingMode.AntialiasingWU: //TODO MyLine myLine3 = new MyLine(canvas); myLine3.firstPoint = new Point(edge.first.X, edge.first.Y); myLine3.secondPoint = new Point(edge.second.X, edge.second.Y); edge.myLine = myLine3; myLine3.DrawAntialiasedWULine(Globals.DefaultEdgeColor); break; case LineDrawingMode.BresenhamSymmetric: MyLine myLine4 = new MyLine(canvas); myLine4.firstPoint = new Point(edge.first.X, edge.first.Y); myLine4.secondPoint = new Point(edge.second.X, edge.second.Y); edge.myLine = myLine4; myLine4.DrawBresenhamSymmetricLine(Globals.DefaultEdgeColor); break; default: break; } }
public bool ApplyRelationChanges(MyEdge movedEdge) { var(success, changedPolygon) = FixRelationsMovingVerticle(movedEdge); if (success == false) { MessageBox.Show("Unallowed Move!", Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Warning); } else { RedrawPolygon(changedPolygon); } return(success); }
public void DeleteRelation() { if (relationType != RelationType.None) { relationIcon.Delete(); relationIcon = null; relationEdge.relationIcon.Delete(); relationEdge.relationIcon = null; relationType = RelationType.None; relationEdge.relationType = RelationType.None; relationEdge.relationEdge = null; relationEdge = null; } }
public void MoveEdgeParallel(MyEdge edge, ref Point startPoint, ref Point endPoint) { var startPointCopy = new Point(startPoint.X, startPoint.Y); var endPointCopy = new Point(endPoint.X, endPoint.Y); edge.MoveParallel(startPoint, endPoint); var result = ApplyRelationChanges(edge); startPoint = endPoint; if (result == false) { edge.MoveParallel(endPointCopy, startPointCopy); startPoint = startPointCopy; endPoint = endPointCopy; } }
public void AddMiddleVerticleOnEdge(MyEdge edge) { edge.DeleteRelation(); var index = Edges.IndexOf(edge); var middleX = (edge.first.X + edge.second.X) / 2.0; var middleY = (edge.first.Y + edge.second.Y) / 2.0; MyPoint middleVerticle = new MyPoint(middleX, middleY); Draw.Verticle(middleVerticle, canvas); MyEdge secondHalf = new MyEdge(middleVerticle, edge.second); Draw.Edge(secondHalf, canvas); edge.second = middleVerticle; edge.MoveWithPoints(); Edges.Insert(index + 1, secondHalf); }
public static void FixEqualRelation(MyPoint first, MyPoint second, MyEdge edge, ref bool endLoop, ref bool success) { var relationEdge = edge.relationEdge; var length = edge.Length(); var relationEdgeLength = relationEdge.Length(); if (length < Globals.eps || relationEdgeLength < Globals.eps) { endLoop = true; success = true; return; } var scale = relationEdgeLength / length; second.X = first.X + (second.X - first.X) * scale; second.Y = first.Y + (second.Y - first.Y) * scale; }
private void ClearVariables() { Polygons.Clear(); ProgramMode = Mode.Pointer; //Pointer Variables IsDraggingOn = false; CurrentDragObjectType = DragObjectType.Nothing; DragStartingPoint = new Point(); DragPolygonId = -1; DragObject = null; //Drawing Variables PolygonDrawing = false; CurrentlyDrawingPolygon = null; PolygonNumber = 0; CurrentLine = null; //Adding Relation Variables RelationPolygonId = -1; RelationSelectedEdge = null; }
private bool DoesUserWantToChangeMode(object sender) { if (ProgramMode == Mode.Draw) { if (ClearUnfinishedPolygon() == false) { var button = sender as RadioButton; button.IsChecked = false; DrawButton.IsChecked = true; return(false); } } else if (ProgramMode == Mode.AddEqualRelation || ProgramMode == Mode.AddPerpendicularRelation) { if (RelationPolygonId != -1) { RelationSelectedEdge.UnselectEdge(); } RelationSelectedEdge = null; RelationPolygonId = -1; } return(true); }
public PolygonDrawResult AddVerticleAndDraw(MyPoint p) { if (MyPoint.AreNear(p, StartingVerticle, (double)Globals.VerticleClickRadiusSize / 2.0) == true) { if (Edges.Count < 2) { return(PolygonDrawResult.NotEnoughEdges); } MyEdge e = new MyEdge(LastVerticle, StartingVerticle); Draw.Edge(e, canvas); Edges.Add(e); return(PolygonDrawResult.DrawFinished); } else { Draw.Verticle(p, canvas); MyEdge e = new MyEdge(LastVerticle, p); Draw.Edge(e, canvas); LastVerticle = p; Edges.Add(e); return(PolygonDrawResult.DrawInProgress); } }
private List <MyEdge> RemoveCollinearEdges() { List <MyEdge> ClearEdges = new List <MyEdge>(); MyEdge tmpEdge = null; MyEdge edge = null; bool AreCollinear = false; for (int i = 0; i < Edges.Count; i++) { if (AreCollinear == true) { edge = tmpEdge; } else { edge = Edges[i]; } var nextEdge = Edges[(i + 1) % Edges.Count]; if (MyPoint.CheckIfCollinear(edge.first, edge.second, nextEdge.second) == true) { tmpEdge = new MyEdge(edge.first, nextEdge.second); AreCollinear = true; if (i == Edges.Count - 1) { var finalEdge = new MyEdge(tmpEdge.first, ClearEdges.First().second); ClearEdges.Add(finalEdge); ClearEdges.RemoveAt(0); } } else { ClearEdges.Add(edge); AreCollinear = false; } } return(ClearEdges); }
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Canvas currentCanvas = sender as Canvas; Point CurrentMousePosition = e.GetPosition(currentCanvas); MyPoint p = new MyPoint(CurrentMousePosition.X, CurrentMousePosition.Y); switch (ProgramMode) { case Mode.Pointer: { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if point hit if (MyPoint.AreNear(edge.first, CurrentMousePosition, Globals.VerticleClickRadiusSize) == true) { CurrentDragObjectType = DragObjectType.Verticle; IsDraggingOn = true; DragPolygonId = pol.Key; DragObject = edge.first; return; } } foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { CurrentDragObjectType = DragObjectType.Edge; IsDraggingOn = true; DragPolygonId = pol.Key; DragObject = edge; DragStartingPoint = CurrentMousePosition; return; } } //check if inside Polygon if (pol.Value.IsPointInside(CurrentMousePosition) == true) { CurrentDragObjectType = DragObjectType.Polygon; IsDraggingOn = true; DragPolygonId = pol.Key; DragObject = pol.Value; DragStartingPoint = CurrentMousePosition; return; } } CurrentDragObjectType = DragObjectType.Nothing; } break; case Mode.Draw: { if (PolygonDrawing == false) { MyPolygon polygon = new MyPolygon(p, currentCanvas); CurrentlyDrawingPolygon = polygon; PolygonDrawing = true; CurrentLine?.DeleteDrawing(); CurrentLine = Draw.SimpleEdge(CurrentMousePosition, CurrentMousePosition, currentCanvas); } else { var DrawResult = CurrentlyDrawingPolygon.AddVerticleAndDraw(p); switch (DrawResult) { case PolygonDrawResult.DrawFinished: CurrentLine.SetFirstPoint(CurrentMousePosition); Polygons.Add(PolygonNumber, CurrentlyDrawingPolygon); CurrentLine.DeleteDrawing(); PolygonDrawing = false; CurrentlyDrawingPolygon = null; PolygonNumber++; break; case PolygonDrawResult.NotEnoughEdges: MessageBox.Show("Not enough edges to finish polygon", Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Warning); break; case PolygonDrawResult.DrawInProgress: CurrentLine.SetFirstPoint(CurrentMousePosition); break; default: break; } } } break; case Mode.AddMiddleVerticle: { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { pol.Value.AddMiddleVerticleOnEdge(edge); return; } } } } break; case Mode.AddEqualRelation: case Mode.AddPerpendicularRelation: { RelationType relationType; if (ProgramMode == Mode.AddEqualRelation) { relationType = RelationType.Equal; } else { relationType = RelationType.Perpendicular; } if (RelationPolygonId == -1) { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.relationType == RelationType.None) { if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { edge.SelectEdge(); RelationSelectedEdge = edge; RelationPolygonId = pol.Key; return; } } } } } else { foreach (var edge in Polygons[RelationPolygonId].Edges) { //check if edge hit if (edge.relationType == RelationType.None) { if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { if (Object.ReferenceEquals(edge, RelationSelectedEdge) == false) { edge.relationEdge = RelationSelectedEdge; RelationSelectedEdge.relationEdge = edge; edge.relationType = relationType; RelationSelectedEdge.relationType = relationType; var result = Polygons[RelationPolygonId].ApplyRelationChanges(edge); if (result == true) { edge.relationIcon = new RelationIcon(edge, relationType, RelationPolygonId, Polygons[RelationPolygonId], currentCanvas); RelationSelectedEdge.relationIcon = new RelationIcon(RelationSelectedEdge, relationType, RelationPolygonId, Polygons[RelationPolygonId], currentCanvas); } else { edge.relationEdge = null; RelationSelectedEdge.relationEdge = null; edge.relationType = RelationType.None; RelationSelectedEdge.relationType = RelationType.None; } } RelationSelectedEdge.UnselectEdge(); RelationSelectedEdge = null; RelationPolygonId = -1; return; } } } } } break; case Mode.DeleteVerticleOrRelation: { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if point hit if (MyPoint.AreNear(edge.first, CurrentMousePosition, Globals.VerticleClickRadiusSize) == true) { if (Polygons[pol.Key].DeleteVerticle(edge.first) == true) { Polygons[pol.Key] = null; Polygons.Remove(pol.Key); } return; } } foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { edge.DeleteRelation(); return; } } } } break; default: break; } return; }
private void PolygonCanvas_MouseMove(object sender, MouseEventArgs e) { Canvas currentCanvas = sender as Canvas; Point CurrentMousePosition = e.GetPosition(currentCanvas); switch (ProgramMode) { case Mode.Pointer: //moving points and edges and polygons { if (IsDraggingOn == true) { switch (CurrentDragObjectType) { case DragObjectType.Verticle: MyPoint verticle = DragObject as MyPoint; Polygons[DragPolygonId].MoveVerticle(verticle, CurrentMousePosition); currentCanvas.Cursor = Cursors.Hand; return; case DragObjectType.Edge: MyEdge movedEdge = DragObject as MyEdge; Polygons[DragPolygonId].MoveEdgeParallel(movedEdge, ref DragStartingPoint, ref CurrentMousePosition); currentCanvas.Cursor = Cursors.Hand; return; case DragObjectType.Polygon: Polygons[DragPolygonId].MovePolygon(ref DragStartingPoint, ref CurrentMousePosition); currentCanvas.Cursor = Cursors.Hand; return; case DragObjectType.Nothing: break; default: break; } } else { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if point hit if (MyPoint.AreNear(edge.first, CurrentMousePosition, Globals.VerticleClickRadiusSize) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } //check if inside Polygon if (pol.Value.IsPointInside(CurrentMousePosition) == true) { currentCanvas.Cursor = Cursors.SizeAll; return; } } } currentCanvas.Cursor = Cursors.Arrow; } break; case Mode.Draw: { if (PolygonDrawing == true) { if (CurrentLine != null) { CurrentLine.SetSecondPoint(CurrentMousePosition); } } } break; case Mode.AddMiddleVerticle: { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } } currentCanvas.Cursor = Cursors.Arrow; } break; case Mode.AddEqualRelation: case Mode.AddPerpendicularRelation: { if (RelationPolygonId == -1) { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.relationType == RelationType.None && edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } } } else { foreach (var edge in Polygons[RelationPolygonId].Edges) { //check if edge hit if (edge.relationType == RelationType.None || Object.ReferenceEquals(edge, RelationSelectedEdge) == true) { if (edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } } } currentCanvas.Cursor = Cursors.Arrow; } break; case Mode.DeleteVerticleOrRelation: { foreach (var pol in Polygons) { foreach (var edge in pol.Value.Edges) { //check if point hit if (MyPoint.AreNear(edge.first, CurrentMousePosition, Globals.VerticleClickRadiusSize) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } foreach (var edge in pol.Value.Edges) { //check if edge hit if (edge.relationType != RelationType.None && edge.IsNearPoint(CurrentMousePosition, Globals.LineClickDistance) == true) { currentCanvas.Cursor = Cursors.Hand; return; } } } currentCanvas.Cursor = Cursors.Arrow; } break; default: break; } }
private (bool success, MyPolygon changedPolygon) FixRelationsMovingVerticle(MyEdge startingEdge) { MyPolygon copyPolygon = this.CopyWithoutDrawing(); var startingEdgeIndex = copyPolygon.Edges.FindIndex(x => x == startingEdge); bool endLoop = false; bool firstSuccess = false; bool secondSuccess = false; //going right (list order) for (int i = 0; i < copyPolygon.Edges.Count && endLoop == false; i++) { var edge = copyPolygon.Edges[(i + startingEdgeIndex) % copyPolygon.Edges.Count]; switch (edge.relationType) { case RelationType.Equal: RelationFixer.FixEqualRelation(edge.first, edge.second, edge, ref endLoop, ref firstSuccess); break; case RelationType.Perpendicular: RelationFixer.FixPerpendicularRelation(edge.first, edge.second, edge.relationEdge.first, edge.relationEdge.second); break; case RelationType.None: endLoop = true; firstSuccess = true; break; default: break; } } if (firstSuccess == false) { return(false, null); } endLoop = false; //going left (no list order) for (int i = copyPolygon.Edges.Count - 1; i >= 0 && endLoop == false; i--) { var edge = copyPolygon.Edges[(i + startingEdgeIndex) % copyPolygon.Edges.Count]; switch (edge.relationType) { case RelationType.Equal: RelationFixer.FixEqualRelation(edge.second, edge.first, edge, ref endLoop, ref secondSuccess); break; case RelationType.Perpendicular: RelationFixer.FixPerpendicularRelation(edge.second, edge.first, edge.relationEdge.second, edge.relationEdge.first); break; case RelationType.None: endLoop = true; secondSuccess = true; break; default: break; } } if (secondSuccess == false) { return(false, null); } return(true, copyPolygon); }
public bool IsPointInside(Point p) { //testing RemoveCollinearEdges //var edgeFirst = Edges[0]; //var edgeThird = Edges[2]; //var myEdge1 = new MyEdge(edgeFirst.second, new MyPoint(edgeFirst.second.X + 50, edgeFirst.second.Y)); //var myEdge2 = new MyEdge(new MyPoint(edgeFirst.second.X + 50, edgeFirst.second.Y), new MyPoint(edgeFirst.second.X + 100, edgeFirst.second.Y)); //edgeThird.first = myEdge2.second; //Edges.RemoveAt(1); //Edges.Insert(1, myEdge2); //Edges.Insert(1, myEdge1); List <MyEdge> ClearEdges = RemoveCollinearEdges(); MyEdge Ray = new MyEdge(new MyPoint(p.X, p.Y), new MyPoint(p.X + canvas.ActualWidth, p.Y)); int intersectCounter = 0; for (int i = 0; i < ClearEdges.Count; i++) { var previousEdge = ClearEdges[(i - 1 + ClearEdges.Count) % ClearEdges.Count]; var edge = ClearEdges[i]; var nextEdge = ClearEdges[(i + 1) % ClearEdges.Count]; if (MyEdge.DoIntersect(edge, Ray) == true) { var firstCollinear = MyPoint.CheckIfCollinear(Ray.first, edge.first, Ray.second); var secondCollinear = MyPoint.CheckIfCollinear(Ray.first, edge.second, Ray.second); if (firstCollinear == true && secondCollinear == true) { //if previosEdge.first i nextEdge.second leza //po przeciwnych stronach polprostej Ray to intersectCounter++ if ((previousEdge.first.Y > Ray.first.Y && nextEdge.second.Y < Ray.first.Y) || (previousEdge.first.Y < Ray.first.Y && nextEdge.second.Y > Ray.first.Y)) { intersectCounter++; } } else if (firstCollinear == true) { //if previousEdge.first i edge.second leza //po przeciwnych stronach polprostej Ray to intersectCounter++ i i++ if ((previousEdge.first.Y > Ray.first.Y && edge.second.Y < Ray.first.Y) || (previousEdge.first.Y < Ray.first.Y && edge.second.Y > Ray.first.Y)) { intersectCounter++; i++; } } else if (secondCollinear == true) { //if edge.first i nextEdge.second leza //po przeciwnych stronach polprostej Ray to intersectCounter++ i i++ if ((edge.first.Y > Ray.first.Y && nextEdge.second.Y < Ray.first.Y) || (edge.first.Y < Ray.first.Y && nextEdge.second.Y > Ray.first.Y)) { intersectCounter++; i++; } } else { intersectCounter++; } } } return(intersectCounter % 2 == 1); }