/* * This routine is used to invert the hole points, specifically the 'Y' points. * The html canvas has 0,0 at the upper left and 'Y' goes down. For the holegroup canvas * we want a 'Y' that goes up, because that's how the holes are overlaid and appear in * three dimensions, and how we think of them intuitively. To manage this we'll simply flip the * Y points for the duration of the time that they are being edited and reflip them when its time to save */ public void InvertHolePoints() { for (int i = 0; i < HoleGroupList.Count; i++) { HoleGroup hg = HoleGroupList.GetFrom(i); for (int j = 0; j < hg.HoleList.Length; j++) { /* * For all hole types the offset Y is inverted */ LayoutHole oHole = hg.HoleList[j]; oHole.OffsetY = -oHole.OffsetY; /* * For polygon hole types the individual Y's are inverted */ if (oHole.HoleType == "poly") { BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex); for (int k = 0; k < oPolygon.PointList.Length; k++) { Point3D p = oPolygon.PointList[k]; p.Y = -p.Y; } } } } }
//------------------------------------------------------ private void DrawShapes_Polygon(LayoutHole oHole, bool IsCurrentHole) { BoundaryPolygon bp = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex); PointF ScreenOffset = this.W2S(oHole.OffsetX, oHole.OffsetY); for (int i = 0; i < bp.PointList.Length; i++) { int FromIndex = i; int ToIndex = i + 1; if (ToIndex == bp.PointList.Length) { ToIndex = 0; // Wrap at end } Point3D FromPoint = bp.PointList[FromIndex]; float fdx = FromPoint.X / CurrentZoom; float fdy = FromPoint.Y / CurrentZoom; Point3D ToPoint = bp.PointList[ToIndex]; float tdx = ToPoint.X / CurrentZoom; float tdy = ToPoint.Y / CurrentZoom; PointF ScreenFrom = new PointF(ScreenOffset.X + fdx, ScreenOffset.Y + fdy); PointF ScreenTo = new PointF(ScreenOffset.X + tdx, ScreenOffset.Y + tdy); // Draw handles string color = "rgba(255,0,0,.5)"; if (IsCurrentHole && i == MostRecentlySelectedPolygonVertexIndex) { color = "#0000FF"; } this.DrawCircle(color, 10, ScreenFrom.X, ScreenFrom.Y); PointF oCenter = EdgeCenter(ScreenFrom, ScreenTo); // Draw the handle for the edge color = "rgba(0,255,0,.5)"; if (IsCurrentHole && i == MostRecentlySelectedPolygonEdgeIndex) { color = "#0000FF"; } this.DrawRectangle(color, 10, 10, oCenter.X, oCenter.Y); // Draw Line this.DrawLine(ShapeStrokeColor, (float)0.5, ScreenFrom, ScreenTo); // Draw the move handle PointF oMove = PolygonCenter(bp); float mdx = oMove.X / CurrentZoom; float mdy = oMove.Y / CurrentZoom; oMove = new PointF(ScreenOffset.X + mdx, ScreenOffset.Y + mdy); color = IsCurrentHole ? "#0000FF" : "rgba(255,0,0,.5)"; // Draw the move handle this.DrawCircle(color, 10, oMove.X, oMove.Y); } }
// If the cur public void SplitCurrentPolygonEdge() { if (MostRecentlySelectedHole == null) { return; } if (MostRecentlySelectedHole.HoleType != "poly") { return; } if (MostRecentlySelectedPolygonEdgeIndex == -1) { return; } BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(MostRecentlySelectedHole.HoleTypeIndex); /* * Locate this edge and create a new point in between the surrounding points */ int FromIndex = MostRecentlySelectedPolygonEdgeIndex; int ToIndex = FromIndex + 1; if (ToIndex == oPolygon.PointList.Length) { ToIndex = 0; } Point3D FromPoint = oPolygon.PointList[FromIndex]; Point3D ToPoint = oPolygon.PointList[ToIndex]; PointF pF = new PointF(FromPoint.X, FromPoint.Y); PointF pT = new PointF(ToPoint.X, ToPoint.Y); PointF oCenter = EdgeCenter(pF, pT); Point3D pNew = new Point3D(); pNew.X = oCenter.X; pNew.Y = oCenter.Y; #if DOTNET List <Point3D> tmp = new List <Point3D>(oPolygon.PointList); tmp.Insert(FromIndex + 1, pNew); oPolygon.PointList = tmp.ToArray(); #else oPolygon.PointList.splice(FromIndex + 1, 0, pNew); #endif // trigger repaint DrawShapes(); }
public void DuplicateCurrentHole() { if (MostRecentlySelectedHole == null) { return; } LayoutHole oHole = LayoutHole.CopyFrom(MostRecentlySelectedHole); // Add at an offset so it will be easy to see oHole.OffsetX += 10; oHole.OffsetY += 10; // Create a new version of the instance of the hole int ndx = MostRecentlySelectedHole.HoleTypeIndex; switch (MostRecentlySelectedHole.HoleType) { case "ell": oHole.HoleTypeIndex = BoundaryEllipseList.Count; BoundaryEllipse e = BoundaryEllipseList.GetFrom(ndx); BoundaryEllipseList.Add(BoundaryEllipse.CopyFrom(e)); break; case "rect": oHole.HoleTypeIndex = BoundaryRectangleList.Count; BoundaryRectangle r = BoundaryRectangleList.GetFrom(ndx); BoundaryRectangleList.Add(BoundaryRectangle.CopyFrom(r)); break; case "poly": oHole.HoleTypeIndex = BoundaryPolygonList.Count; BoundaryPolygon p = BoundaryPolygonList.GetFrom(ndx); BoundaryPolygonList.Add(BoundaryPolygon.CopyFrom(p)); break; } // Add the new hole to the hole group AddHoleToHoleGroup(MostRecentlySelectedHoleGroup, oHole); // trigger a repaint DrawShapes(); }
public void RemoveCurrentPolygonVertex() { if (MostRecentlySelectedHole == null) { return; } if (MostRecentlySelectedHole.HoleType != "poly") { return; } if (MostRecentlySelectedPolygonVertexIndex == -1) { return; } BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(MostRecentlySelectedHole.HoleTypeIndex); // Don't reduce to less than 3 points if (oPolygon.PointList.Length == 3) { return; } /* * Remove this point and clear the most recently selected edge */ #if DOTNET List <Point3D> tmp = new List <Point3D>(oPolygon.PointList); tmp.RemoveAt(MostRecentlySelectedPolygonVertexIndex); oPolygon.PointList = tmp.ToArray(); #else oPolygon.PointList.splice(this.MostRecentlySelectedPolygonVertexIndex, 1); #endif MostRecentlySelectedPolygonVertexIndex = -1; // trigger a redraw DrawShapes(); }
//------------------------------------------------------------------------------------------------ protected void UpdatePolygon(int ScreenMouseX, int ScreenMouseY, int ScreenDeltaX, int ScreenDeltaY) { BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(CurrentlySelectedHole.HoleTypeIndex); PointF pWorld = this.S2W(ScreenMouseX, ScreenMouseY); float newx = pWorld.X; float newy = pWorld.Y; // Update the world points to the nearest grid if (this.GridSize > 1) { newx = this.RoundToGrid((int)pWorld.X); newy = this.RoundToGrid((int)pWorld.Y); } switch (CurrentlySelectedHandleType) { case eHandleType.VertexHandle: /* * Retrieve this vertex and update */ Point3D p = oPolygon.PointList[CurrentlySelectedPolygonVertexIndex]; p.X += ScreenDeltaX * CurrentZoom; p.Y += ScreenDeltaY * CurrentZoom; break; case eHandleType.EdgeHandle: /* * The points associated with the edge are the ones at the value and after */ int FromIndex = CurrentlySelectedPolygonEdgeIndex; int ToIndex = FromIndex + 1; if (ToIndex == oPolygon.PointList.Length) { ToIndex = 0; } Point3D FromPoint = oPolygon.PointList[FromIndex]; Point3D ToPoint = oPolygon.PointList[ToIndex]; FromPoint.X += ScreenDeltaX * CurrentZoom; FromPoint.Y += ScreenDeltaY * CurrentZoom; ToPoint.X += ScreenDeltaX * CurrentZoom; ToPoint.Y += ScreenDeltaY * CurrentZoom; break; case eHandleType.MoveHandle: /* * Update the offset to move the whole shape */ CurrentlySelectedHole.OffsetX = newx; CurrentlySelectedHole.OffsetY = newy; /* * Update all points with the delta */ #if false for (int i = 0; i < oPolygon.PointList.Length; i++) { Point3D pMove = oPolygon.PointList[i]; pMove.X += ScreenDeltaX; pMove.Y += ScreenDeltaY; } #endif break; } }
//-------------------------------------------------------------------------- /* * A Polygon can be selected in any of these ways: * 1. A vertex can be selected, which makes it the active vertex * 2. An edge can be selected, which makes it the active edge * 3. The move handle can be selected. The move handle is generated as the average of the points of the polygon */ private bool TrySelectPolygon(LayoutHole oHole, int ScreenMouseX, int ScreenMouseY) { PointF MoveHandle = new PointF(0, 0); float dx; float dy; BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex); PointF ScreenOffset = this.W2S(oHole.OffsetX, oHole.OffsetY); /* * See if this is one of the vertices */ for (int i = 0; i < oPolygon.PointList.Length; i++) { Point3D p = oPolygon.PointList[i]; dx = p.X / CurrentZoom; dy = p.Y / CurrentZoom; PointF Target = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy); if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, Target)) { CurrentlySelectedHole = oHole; // Most recently selected is used for commands that happen after the mouse is up MostRecentlySelectedHole = oHole; CurrentlySelectedHandleType = eHandleType.VertexHandle; CurrentlySelectedPolygonVertexIndex = i; // The most recently used is for commands that happen after the mouse is up MostRecentlySelectedPolygonVertexIndex = i; return(true); } } /* * See if this is one of the edges */ for (int i = 0; i < oPolygon.PointList.Length; i++) { int FromIndex = i; int ToIndex = i + 1; if (ToIndex == oPolygon.PointList.Length) { ToIndex = 0; } Point3D FromPoint = oPolygon.PointList[FromIndex]; dx = FromPoint.X / CurrentZoom; dy = FromPoint.Y / CurrentZoom; PointF pFrom = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy); Point3D ToPoint = oPolygon.PointList[ToIndex]; dx = ToPoint.X / CurrentZoom; dy = ToPoint.Y / CurrentZoom; PointF pTo = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy); PointF Target = EdgeCenter(pFrom, pTo); if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, Target)) { CurrentlySelectedHole = oHole; // Most recently selected is used for commands that happen after the mouse is up MostRecentlySelectedHole = oHole; CurrentlySelectedHandleType = eHandleType.EdgeHandle; CurrentlySelectedPolygonEdgeIndex = i; // The most recently used is for commands that happen after the mouse is up MostRecentlySelectedPolygonEdgeIndex = i; return(true); } } /* * See if this is the move handle at the center of the polygon */ PointF pCenter = PolygonCenter(oPolygon); dx = pCenter.X / CurrentZoom; dy = pCenter.Y / CurrentZoom; pCenter = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy); if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, pCenter)) { CurrentlySelectedHole = oHole; // Most recently selected is used for commands that happen after the mouse is up MostRecentlySelectedHole = oHole; CurrentlySelectedHandleType = eHandleType.MoveHandle; return(true); } return(false); }