public static void nearest_point_from_segment_list(int x, int y, ArrayList /* of GuiPoint */ list, out int segnum, out int rx, out int ry) { GuiPoint p = (GuiPoint)list[0]; Point p1 = new Point(p.x, p.y), p2 = new Point(0, 0); double mindist = -1; int x2, y2; int i = 1; segnum = 0; rx = p.x; ry = p.y; do { p = (GuiPoint)list[i]; p2.X = p.x; p2.Y = p.y; nearest_point_from_segment(x, y, p1, p2, out x2, out y2); double dist = Math.Sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); if (dist < mindist || mindist < -0.5f) { segnum = i - 1; rx = x2; ry = y2; mindist = dist; } p1 = p2; i++; } while(i < list.Count); }
private void show_points() { System.Diagnostics.Debug.WriteLine("conection: " + conn.ID); for (int i = 0; i < conn.ipoints.Count; i++) { GuiPoint pt = conn.ipoints[i] as GuiPoint; System.Diagnostics.Debug.WriteLine("[" + i + "]: (" + pt.x + "," + pt.y + ")"); } }
// Params: ptnum - point number // Returns: false - drag point ptnum, true - drag segment segnum private bool move_quadric_point(ref int ptnum, out int segnum, int to_x, int to_y) { GuiPoint neighbour = conn.ipoints[ptnum - 1] as GuiPoint; GuiPoint move_point = conn.ipoints[ptnum] as GuiPoint; bool vertical; int delta, n, affected; bool ret = false; segnum = 0; for (int i = -1; i < 1; i++) { vertical = (neighbour.x - move_point.x) == 0; n = ptnum + i; delta = (vertical) ? to_x - move_point.x : to_y - move_point.y; if (delta != 0) { n = move_quadric_segment(ref n, vertical, delta, out affected, true); // if the transformation affects the first connection point, // then we have to change the point being moved if (affected == -1) { if (n == 0) { ptnum++; } } else { if (!conn.ipoints.Contains(move_point)) { if (affected != 0) { segnum = affected - 1; } ret = true; } else { ptnum = conn.ipoints.IndexOf(move_point); } } } if (ptnum < conn.ipoints.Count - 1) { neighbour = conn.ipoints[ptnum + 1] as GuiPoint; } else { break; } } return(ret); }
public static void nearest_point_from_rect( int x, int y, Rectangle r, out int rx, out int ry ) { GuiPoint[] p = new GuiPoint[] { new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint() }; p[1].x = p[0].x = r.Left; p[3].y = p[0].y = r.Top; p[3].x = p[2].x = r.Right; p[1].y = p[2].y = r.Bottom; p[4] = p[0]; int segn; nearest_point_from_segment_list( x, y, new ArrayList(p), out segn, out rx, out ry ); }
public static void nearest_point_from_rect(int x, int y, Rectangle r, out int rx, out int ry) { GuiPoint[] p = new GuiPoint[] { new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint(), new GuiIntermPoint() }; p[1].x = p[0].x = r.Left; p[3].y = p[0].y = r.Top; p[3].x = p[2].x = r.Right; p[1].y = p[2].y = r.Bottom; p[4] = p[0]; int segn; nearest_point_from_segment_list(x, y, new ArrayList(p), out segn, out rx, out ry); }
private void DrawSegmentedConnection(Graphics g, Rectangle r, int offx, int offy) { int x1 = first.x + r.X - offx, y1 = first.y + r.Y - offy; int x2, y2; Pen color = selected ? Pens.Blue : Pens.Black, p = color; switch (type) { case UmlRelationType.Attachment: case UmlRelationType.Dependency: case UmlRelationType.Realization: p = new Pen(p.Color); p.DashStyle = DashStyle.Dash; p.DashOffset = 0; p.DashPattern = new float[] { 10, 5 }; break; default: g.SmoothingMode = SmoothingMode.HighQuality; break; } Point[] pnts = new Point[ipoints.Count]; for (int i = 0; i < ipoints.Count; i++) { GuiPoint pt = (GuiPoint)ipoints[i]; pnts[i].X = pt.x + r.X - offx; pnts[i].Y = pt.y + r.Y - offy; } g.DrawLines(p, pnts); GuiPoint pnt = (GuiPoint)ipoints[1]; x2 = pnt.x + r.X - offx; y2 = pnt.y + r.Y - offy; switch (type) { case UmlRelationType.Aggregation: case UmlRelationType.Composition: Geometry.point_rhomb_on_segment(out pnts, x1, y1, x2, y2, 7, 5); g.FillPolygon(type == UmlRelationType.Composition ? Brushes.Black : Brushes.White, pnts); g.DrawPolygon(color, pnts); if (nav == GuiConnectionNavigation.Left) { x1 = pnts[2].X; y1 = pnts[2].Y; goto case UmlRelationType.Association; } else if (nav == GuiConnectionNavigation.Right) { goto case UmlRelationType.Association; } break; case UmlRelationType.Association: if (nav == GuiConnectionNavigation.Left) { Geometry.point_triangle_on_segment(out pnts, x1, y1, x2, y2, 7, 5); g.DrawLines(color, pnts); } else if (nav == GuiConnectionNavigation.Right) { pnt = (GuiPoint)ipoints[ipoints.Count - 2]; x1 = second.x + r.X - offx; y1 = second.y + r.Y - offy; x2 = pnt.x + r.X - offx; y2 = pnt.y + r.Y - offy; Geometry.point_triangle_on_segment(out pnts, x1, y1, x2, y2, 7, 5); g.DrawLines(color, pnts); } break; case UmlRelationType.Inheritance: case UmlRelationType.Realization: Geometry.point_triangle_on_segment(out pnts, x1, y1, x2, y2, 10, 7); g.FillPolygon(Brushes.White, pnts); g.DrawPolygon(color, pnts); break; case UmlRelationType.Dependency: Geometry.point_triangle_on_segment(out pnts, x1, y1, x2, y2, 7, 5); g.DrawLines(color, pnts); break; case UmlRelationType.Attachment: break; } g.SmoothingMode = SmoothingMode.Default; switch (type) { case UmlRelationType.Attachment: case UmlRelationType.Dependency: case UmlRelationType.Realization: p.Dispose(); break; } }
// Params: // segnum - segment number (0..), vertical_sement, delta (offset in points) // affected_segment (if check is set), check - call collapse_quadric_segments // Returns: // 0 - the transformation affects the first connection point (new segment has been inserted ), // 1 - the transformation affects only intermediate points // 2 - the transformation affects the second connection point private int move_quadric_segment(ref int segnum, bool vertical_segment, int delta, out int affected_segment, bool check) { GuiIntermPoint pt = null; GuiPoint orig_pt; int ret = -1; affected_segment = -1; if (delta == 0) { return(ret); } conn.Invalidate(); if (conn.ipoints.Count == 2) { GuiIntermPoint pt2; pt = conn.insert_point(0); pt2 = conn.insert_point(1); pt.x = conn.first.x; pt.y = conn.first.y; pt2.x = conn.second.x; pt2.y = conn.second.y; if (vertical_segment) { pt.x += delta; pt2.x += delta; } else { pt.y += delta; pt2.y += delta; } conn.add_child(pt, null); conn.add_child(pt2, null); segnum = 1; ret = 0; } else { if (segnum != 0) { orig_pt = conn.ipoints[segnum] as GuiPoint; } else { orig_pt = conn.ipoints[1] as GuiPoint; } if (vertical_segment) { orig_pt.x += delta; } else { orig_pt.y += delta; } // the last segment if (segnum == conn.ipoints.Count - 2) { pt = conn.insert_point(segnum); if (vertical_segment) { pt.x = orig_pt.x; pt.y = conn.second.y; } else { pt.y = orig_pt.y; pt.x = conn.second.x; } ret = 2; // the first segment } else if (segnum == 0) { pt = conn.insert_point(0); if (vertical_segment) { pt.x = orig_pt.x; pt.y = conn.first.y; } else { pt.y = orig_pt.y; pt.x = conn.first.x; } segnum = 1; ret = 0; // some segment in the middle } else { GuiPoint sec = conn.ipoints[segnum + 1] as GuiPoint; if (vertical_segment) { sec.x += delta; } else if (!vertical_segment) { sec.y += delta; } ret = 1; } if (pt != null) { conn.add_child(pt, null); } } if (check) { collapse_quadric_segments(ref segnum, out affected_segment); } conn.Invalidate(); return(ret); }