/// <summary> /// displays the database /// </summary> /// <param name="db"></param> /// <param name="curves"></param> static public void ShowDataBase(Database db, params Splines.ICurve[] curves) { Microsoft.Msagl.Drawing.Graph g = new Microsoft.Msagl.Drawing.Graph(""); AllocateDebugCurves(g); Microsoft.Msagl.Splines.Rectangle graphBox = new Microsoft.Msagl.Splines.Rectangle(db.Anchors[0].LeftTop); List <ICurve> cl = new List <ICurve>(curves); foreach (Anchor a in db.Anchors) { graphBox.Add(a.LeftTop); graphBox.Add(a.RightBottom); cl.Add(a.PolygonalBoundary); } AddCurvesToGraph(cl, g); Microsoft.Msagl.Point del = (graphBox.LeftBottom - graphBox.RightTop) / 10; graphBox.Add(graphBox.LeftBottom + del); graphBox.Add(graphBox.RightTop - del); GeometryGraph gg = new GeometryGraph(); gg.BoundingBox = graphBox; g.DataBase = db; g.GeometryGraph = gg; DisplayGraph(g); db.nodesToShow = null; }
private void ProcessRightClickOnSelectedEdge(MsaglMouseEventArgs e) { mouseRightButtonDownPoint = viewer.ScreenToSource(e); cornerInfo = AnalyzeInsertOrDeletePolylineCorner(mouseRightButtonDownPoint, this.SelectedEdge.RadiusOfPolylineCorner); if (cornerInfo == null) { return; } e.Handled = true; Couple <string, DelegateReturningVoid> edgeRemoveCouple = new Couple <string, DelegateReturningVoid>("Remove edge", delegate() { this.viewer.RemoveEdge(this.SelectedEdge, true); }); if (cornerInfo.Second == Microsoft.Msagl.Drawing.PolylineCornerType.PreviousCornerForInsertion) { viewer.PopupMenus(new Couple <string, DelegateReturningVoid>("Insert polyline corner", new DelegateReturningVoid(this.InsertPolylineCorner)), edgeRemoveCouple); } else if (cornerInfo.Second == Microsoft.Msagl.Drawing.PolylineCornerType.CornerToDelete) { viewer.PopupMenus(new Couple <string, DelegateReturningVoid>("Delete polyline corner", new DelegateReturningVoid(this.DeleteCorner)), edgeRemoveCouple); } }
static bool WithinEpsilon(Microsoft.Msagl.Splines.ICurve bc, double start, double end) { int n = 3; //hack !!!! double d = (end - start) / n; P2 s = bc[start]; P2 e = bc[end]; return(DistToSegm(bc[start + d], s, e) < epsilon && DistToSegm(bc[start + d * (n - 1)], s, e) < epsilon); }
internal static double DistToSegm(P2 p, P2 s, P2 e) { P2 l = e - s; double len = l.Length; if (len < Tessellator.epsilon) { return((p - (0.5f * (s + e))).Length); } P2 perp = new P2(-l.Y, l.X); perp /= len; return(Math.Abs((p - s) * perp)); }
//when we check for inclusion we expand the box by slack internal Geometry Hit(P2 p, double slack) { if (l == null) { if (Box.Contains(p, slack)) { Line line = geometry as Line; if (line != null) { if (Tessellator.DistToSegm(p, line.start, line.end) < slack + line.LineWidth / 2) { return(line); } return(null); } else if (Box.Contains(p)) { return(geometry); } return(null); } else { return(null); } } if (l.Box.Contains(p, slack)) { Geometry g = l.Hit(p, slack); if (g != null) { return(g); } } if (r.Box.Contains(p, slack)) { Geometry g = r.Hit(p, slack); if (g != null) { return(g); } } return(null); }
private static void AddUnderlyingPolylineTessellation(List <ObjectWithBox> list, DEdge edge, double radiusForUnderlyingPolylineCorners) { P2 rad = new P2(radiusForUnderlyingPolylineCorners, radiusForUnderlyingPolylineCorners); IEnumerator <P2> en = edge.DrawingEdge.Attr.GeometryEdge.UnderlyingPolyline.GetEnumerator(); en.MoveNext(); P2 p = en.Current; list.Add(new Geometry(edge, new BBox(p + rad, p - rad))); while (en.MoveNext()) { list.Add(new Line(edge, p, p = en.Current, edge.DrawingEdge.Attr.LineWidth)); list.Add(new Geometry(edge, new BBox(p + rad, p - rad))); } }
const double arrowAngle = 25.0;//degrees static internal void DrawArrow(Graphics g, Brush brush, P2 start, P2 end, int lineWidth, ArrowStyle arrowStyle) { switch (arrowStyle) { case ArrowStyle.NonSpecified: case ArrowStyle.Normal: DrawNormalArrow(g, brush, ref start, ref end, lineWidth); break; case ArrowStyle.Tee: DrawTeeArrow(g, brush, ref start, ref end, lineWidth); break; default: throw new InvalidOperationException(); } }
private static void DrawTeeArrow(Graphics g, Brush brush, ref P2 start, ref P2 end, int lineWidth) { double lw = lineWidth == -1 ? 1 : lineWidth; using (Pen p = new Pen(brush, (float)lw)) { g.DrawLine(p, P2ToPointF(start), P2ToPointF(end)); P2 dir = end - start; P2 h = dir; dir /= dir.Length; P2 s = new P2(-dir.Y, dir.X); s *= 2 * h.Length * ((float)Math.Tan(arrowAngle * 0.5f * (Math.PI / 180.0))); s += (1 + lw) * s.Normalize(); g.DrawLine(p, P2ToPointF(start + s), P2ToPointF(start - s)); } }
protected override void OnMouseUp(MouseEventArgs args) { base.OnMouseUp(args); MsaglMouseEventArgs iArgs = CreateMouseEventArgs(args); gViewer.RaiseMouseUpEvent(iArgs); if (NeedToEraseRubber) { DrawXORFrame(); } if (!iArgs.Handled) { if (gViewer.OriginalGraph != null && MouseDraggingMode == DraggingMode.WindowZoom) { System.Drawing.Point p = mouseDownPoint; double f = Math.Max(Math.Abs(p.X - args.X), Math.Abs(p.Y - args.Y)) / GViewer.dpi; if (f > gViewer.ZoomWindowThreshold && zoomWindow) { mouseUpPoint = new System.Drawing.Point(args.X, args.Y); if (ClientRectangle.Contains(mouseUpPoint)) { System.Drawing.Rectangle r = GViewer.RectFromPoints(mouseDownPoint, mouseUpPoint); r.Intersect(gViewer.DestRect); if (GViewer.ModifierKeyWasPressed() == false) { mouseDownPoint.X = r.Left; mouseDownPoint.Y = r.Top; mouseUpPoint.X = r.Right; mouseUpPoint.Y = r.Bottom; P2 p1 = gViewer.ScreenToSource(mouseDownPoint); P2 p2 = gViewer.ScreenToSource(mouseUpPoint); double sc = Math.Min((double)ClientRectangle.Width / r.Width, (double)ClientRectangle.Height / (double)r.Height); P2 center = 0.5f * (p1 + p2); gViewer.Zoom(center.X, center.Y, sc * gViewer.ZoomF); } } } } } zoomWindow = false; }
internal Line(DObject tag, P2 start, P2 end, double lw) : base(tag) { lineWidth = lw; P2 dir = end - start; if (lineWidth < 0) { lineWidth = 1; } double len = dir.Length; if (len > Microsoft.Msagl.Splines.Curve.IntersectionEpsilon) { dir /= (len / (lineWidth / 2)); dir = dir.Rotate(Math.PI / 2); } else { dir.X = 0; dir.Y = 0; } this.bBox = new Microsoft.Msagl.Splines.Rectangle(start + dir); this.bBox.Add(start - dir); this.bBox.Add(end + dir); this.bBox.Add(end - dir); this.start = start; this.end = end; if (this.bBox.LeftTop.X == this.bBox.RightBottom.X) { bBox.LeftTop = bBox.LeftTop + new P2(-0.05f, 0); bBox.RightBottom = bBox.RightBottom + new P2(0.05f, 0); } if (this.bBox.LeftTop.Y == this.bBox.RightBottom.Y) { bBox.LeftTop = bBox.LeftTop + new P2(0, -0.05f); bBox.RightBottom = bBox.RightBottom + new P2(0, 0.05f); } }
private static void ShowCurvesWithColorsSet(IEnumerable <Microsoft.Msagl.Splines.ICurve> curves, Microsoft.Msagl.Drawing.Graph g) { AllocateDebugCurves(g); // g.ShowControlPoints = true; Microsoft.Msagl.Splines.Rectangle graphBox = new Microsoft.Msagl.Splines.Rectangle(); AddCurvesToGraph(curves, g); bool firstTime = true; foreach (Microsoft.Msagl.Splines.ICurve c0 in curves) { if (c0 != null) { Microsoft.Msagl.Splines.Parallelogram b = c0.ParallelogramNodeOverICurve.Parallelogram; for (int i = 0; i < 4; i++) { if (firstTime) { firstTime = false; graphBox = new Rectangle(b.Vertex((VertexId)i)); } graphBox.Add(b.Vertex((VertexId)i)); } } } Microsoft.Msagl.Point del = (graphBox.LeftBottom - graphBox.RightTop) / 10; graphBox.Add(graphBox.LeftBottom + del); graphBox.Add(graphBox.RightTop - del); GeometryGraph gg = new GeometryGraph(); gg.BoundingBox = graphBox; g.GeometryGraph = gg; try { DisplayGraph(g); } catch (Exception e) { Console.WriteLine(e); } }
private static void DrawNormalArrow(Graphics g, Brush brush, ref P2 start, ref P2 end, int lineWidth) { PointF[] points; if (lineWidth == 1) { P2 dir = end - start; P2 h = dir; dir /= dir.Length; P2 s = new P2(-dir.Y, dir.X); s *= h.Length * ((float)Math.Tan(arrowAngle * 0.5f * (Math.PI / 180.0))); points = new PointF[] { P2ToPointF(start + s), P2ToPointF(end), P2ToPointF(start - s) }; } else { P2 dir = end - start; P2 h = dir; dir /= dir.Length; P2 s = new P2(-dir.Y, dir.X); float w = (float)(0.5f * lineWidth); P2 s0 = w * s; double al = arrowAngle * 0.5f * (double)(Math.PI / 180.0); s *= h.Length * ((float)Math.Tan(al)); s += s0; points = new PointF[] { P2ToPointF(start + s), P2ToPointF(start - s), P2ToPointF(end - s0), P2ToPointF(end + s0) }; P2 center = end - dir * w * (float)Math.Tan(al); double rad = w / (double)Math.Cos(al); g.FillEllipse(brush, (float)center.X - (float)rad, (float)center.Y - (float)rad, 2.0f * (float)rad, 2.0f * (float)rad); } g.FillPolygon(brush, points); }
void viewer_MouseDown(object sender, MsaglMouseEventArgs e) { if (viewer.LayoutIsEditable) { PressedMouseButtons = GetPressedButtons(e); mouseDownSourcePoint = viewer.ScreenToSource(e); mouseDownScreenPoint = new Point(e.X, e.Y); if (e.LeftButtonIsPressed) { LeftMouseButtonWasPressed = true; if (!(viewer.ObjectUnderMouseCursor is IViewerEdge)) { ActiveDraggedObject = viewer.ObjectUnderMouseCursor; } if (ActiveDraggedObject != null) { e.Handled = true; } if (this.SelectedEdge != null) { this.CheckIfDraggingPolylineVertex(e); } } else if (e.RightButtonIsPressed) { if (this.SelectedEdge != null) { ProcessRightClickOnSelectedEdge(e); } } else if (e.MiddleButtonIsPressed && viewer.ObjectUnderMouseCursor is IViewerNode) { SourceOfInsertedEdge = viewer.ObjectUnderMouseCursor as IViewerNode; UnselectEverything(); MiddleMouseButtonWasPressed = true; viewer.StartDrawingRubberLine(e); } } }
public Couple <Site, PolylineCornerType> AnalyzeInsertOrDeletePolylineCorner(Point point, double tolerance) { if (this.SelectedEdge == null) { return(null); } tolerance += this.SelectedEdge.Edge.Attr.LineWidth; Site corner = GeometryGraphEditor.GetPreviousSite(SelectedEdge.Edge.Attr.GeometryEdge, point); if (corner != null) { return(new Couple <Site, PolylineCornerType>(corner, PolylineCornerType.PreviousCornerForInsertion)); } corner = GeometryGraphEditor.FindCornerForEdit(this.SelectedEdge.Edge.Attr.GeometryEdge.UnderlyingPolyline, point, tolerance); if (corner != null) { return(new Couple <Site, PolylineCornerType>(corner, PolylineCornerType.CornerToDelete)); } return(null); }
internal PointF PointF(P2 p) { return(new PointF((float)p.X, (float)p.Y)); }
static internal void DrawLine(Graphics g, Pen pen, P2 start, P2 end) { g.DrawLine(pen, P2ToPointF(start), P2ToPointF(end)); }
private void selectNode(direction direction) { if (this._selectedNode != null) { Microsoft.Msagl.Point selectedNodePosition = default(Microsoft.Msagl.Point); selectedNodePosition = _selectedNode.Attr.Pos; Node nearestNode = null; double nearestRange = 0; double checkingRange = 0; //check each node foreach (Node checkingNode in _gViewer.Graph.NodeMap.Values) { //except the selected one ;) if (!ReferenceEquals(checkingNode, _selectedNode)) { switch (direction) { case direction.up: case direction.down: //check for Y-axis //check if the direction is up and the node which should be checked is upper //or the direction is down and the node is lower if ((direction == direction.up && checkingNode.Attr.Pos.Y > selectedNodePosition.Y) || (direction == direction.down && checkingNode.Attr.Pos.Y < selectedNodePosition.Y)) { //if the node is valid check fi there is allready a "nearest node" if (nearestNode == null) { //if not save the node and the range between the selected node and the checked node nearestNode = checkingNode; nearestRange = getRange(checkingNode.Attr.Pos, selectedNodePosition); } else { checkingRange = getRange(checkingNode.Attr.Pos, selectedNodePosition); //check if the selected node is nearer then the nearest node if (checkingRange < nearestRange) { nearestNode = checkingNode; nearestRange = checkingRange; } } } break; case direction.right: case direction.left: //check X-axis same way if ((direction == direction.right && checkingNode.Attr.Pos.X > selectedNodePosition.X) || (direction == direction.left && checkingNode.Attr.Pos.X < selectedNodePosition.X)) { if (nearestNode == null) { nearestNode = checkingNode; nearestRange = getRange(checkingNode.Attr.Pos, selectedNodePosition); } else { checkingRange = getRange(checkingNode.Attr.Pos, selectedNodePosition); if (checkingRange < nearestRange) { nearestNode = checkingNode; nearestRange = checkingRange; } } } break; } } } //if there is a nearest node if (nearestNode != null) { selectNode(nearestNode.Id); //select it } } }
static PointF P2ToPointF(P2 p) { return(new PointF((float)p.X, (float)p.Y)); }
private bool MouseScreenPointIsCloseEnoughToVertex(Point point, double radius) { return((point - this.mouseDownSourcePoint).Length < radius); }
private double getRange(Microsoft.Msagl.Point position1, Microsoft.Msagl.Point position2) { return(Math.Max(position1.X, position2.X) - Math.Min(position1.X, position2.X) + Math.Max(position1.Y, position2.Y) - Math.Min(position1.Y, position2.Y)); }
public void InsertPolylineCorner(Point point, Site previousCorner) { this.viewer.InvalidateBeforeTheChange(SelectedEdge); this.geomGraphEditor.InsertSite(this.SelectedEdge.Edge.Attr.GeometryEdge, point, previousCorner, SelectedEdge); this.viewer.Invalidate(SelectedEdge); }