private void DrawStuffForSelectedPart(Graphics2D graphics2D) { if (SelectedMeshGroup != null) { AxisAlignedBoundingBox selectedBounds = SelectedMeshGroup.GetAxisAlignedBoundingBox(SelectedMeshGroupTransform.TotalTransform); Vector3 boundsCenter = selectedBounds.Center; Vector3 centerTop = new Vector3(boundsCenter.x, boundsCenter.y, selectedBounds.maxXYZ.z); Vector2 centerTopScreenPosition = meshViewerWidget.TrackballTumbleWidget.GetScreenPosition(centerTop); centerTopScreenPosition = meshViewerWidget.TransformToParentSpace(this, centerTopScreenPosition); //graphics2D.Circle(screenPosition.x, screenPosition.y, 5, RGBA_Bytes.Cyan); PathStorage zArrow = new PathStorage(); zArrow.MoveTo(-6, -2); zArrow.curve3(0, -4); zArrow.LineTo(6, -2); zArrow.LineTo(0, 12); zArrow.LineTo(-6, -2); VertexSourceApplyTransform translate = new VertexSourceApplyTransform(zArrow, Affine.NewTranslation(centerTopScreenPosition)); //graphics2D.Render(translate, RGBA_Bytes.Black); } }
public static IVertexSource CreatePathStorage(string data) { PathStorage path = new PathStorage(); bool hasCurves = false; //todo 依次输入多个同一类型的命令时,可以省略重复的命令项;例如,L 100,200 300,400 等同于 L 100,200 L 300,400。 StringBuilder buffer = new StringBuilder(); for (int i = 0; i < data.Length; i++) { if (data[i] == '-' && i > 0 && data[i - 1] != ',' && data[i - 1] != ' ' && char.IsLetter(data[i - 1]) == false) { buffer.Append(','); } if (data[i] != 'F' && (char.IsLetter(data[i]))) { buffer.Append(','); buffer.Append(data[i]); if (i < data.Length - 1 && data[i + 1] != ' ') buffer.Append(','); } else { buffer.Append(data[i]); } } string[] commands = buffer.ToString().Split(new char[] { ' ', ',' }); MatterHackers.VectorMath.Vector2 polyStart = new MatterHackers.VectorMath.Vector2(0, 0); MatterHackers.VectorMath.Vector2 lastXY = new MatterHackers.VectorMath.Vector2(0, 0); MatterHackers.VectorMath.Vector2 curXY = new MatterHackers.VectorMath.Vector2(); for (int i = 0; i < commands.Length; i++) { switch (commands[i]) { // F0 指定 EvenOdd 填充规则。F1 指定 Nonzero 填充规则。 // 如果省略此命令,则子路径使用默认行为,即 EvenOdd。 如果指定此命令,则必须将其置于最前面。 case "F1": break; case " ": break; case "m": case "M": { curXY.x = double.Parse(commands[i + 1]); curXY.y = double.Parse(commands[i + 2]); if (commands[i] == "m") { curXY += lastXY; } path.MoveTo(curXY.x, curXY.y); polyStart = curXY; i += 2; } break; case "l": case "L": { curXY.x = double.Parse(commands[i + 1]); curXY.y = double.Parse(commands[i + 2]); if (commands[i] == "l") { curXY += lastXY; } path.LineTo(curXY.x, curXY.y); } break; case "h": case "H": { curXY.y = lastXY.y; curXY.x = double.Parse(commands[i + 1]); if (commands[i] == "h") { curXY.x += lastXY.x; } path.HorizontalLineTo(curXY.x); i += 1; } break; case "v": case "V": { curXY.x = lastXY.x; curXY.y = double.Parse(commands[i + 1]); if (commands[i] == "v") { curXY.y += lastXY.y; } path.VerticalLineTo(curXY.y); i += 1; } break; //三次方贝塞尔曲线命令。通过使用两个指定的控制点(controlPoint1 和 controlPoint2)在当前点与指定的终点之间创建一条三次方贝塞尔曲线 case "c": case "C": { MatterHackers.VectorMath.Vector2 controlPoint1; MatterHackers.VectorMath.Vector2 controlPoint2; controlPoint1.x = double.Parse(commands[i + 1]); controlPoint1.y = double.Parse(commands[i + 2]); controlPoint2.x = double.Parse(commands[i + 3]); controlPoint2.y = double.Parse(commands[i + 4]); curXY.x = double.Parse(commands[i + 5]); curXY.y = double.Parse(commands[i + 6]); if (commands[i] == "c") { controlPoint1 += lastXY; controlPoint2 += lastXY; curXY += lastXY; } path.curve4(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, curXY.x, curXY.y); i += 6; hasCurves = true; } break; //二次贝塞尔曲线命令。通过使用指定的控制点 (controlPoint) 在当前点与指定的终点之间创建一条二次贝塞尔曲线。 case "q": case "Q": { MatterHackers.VectorMath.Vector2 controlPoint; controlPoint.x = double.Parse(commands[i + 1]); controlPoint.y = double.Parse(commands[i + 2]); curXY.x = double.Parse(commands[i + 3]); curXY.y = double.Parse(commands[i + 4]); if (commands[i] == "q") { controlPoint += lastXY; curXY += lastXY; } path.curve3(controlPoint.x, controlPoint.y, curXY.x, curXY.y); i += 4; hasCurves = true; } break; //在当前点与指定的终点之间创建一条三次方贝塞尔曲线。 //第一个控制点假定为前一个命令的第二个控制点相对于当前点的反射。 //如果前一个命令不存在,或者前一个命令不是三次方贝塞尔曲线命令或平滑的三次方贝塞尔曲线命令,则假定第一个控制点就是当前点。 //第二个控制点,即曲线终端的控制点,由 controlPoint2 指定。 case "s": case "S": { MatterHackers.VectorMath.Vector2 controlPoint2; controlPoint2.x = double.Parse(commands[i + 1]); controlPoint2.y = double.Parse(commands[i + 2]); curXY.x = double.Parse(commands[i + 3]); curXY.y = double.Parse(commands[i + 4]); if (commands[i] == "s") { controlPoint2 += lastXY; curXY += lastXY; } path.curve4(controlPoint2.x, controlPoint2.y, curXY.x, curXY.y); i += 4; hasCurves = true; } break; //二次贝塞尔曲线命令。在当前点与指定的终点之间创建一条二次贝塞尔曲线。 //控制点假定为前一个命令的控制点相对于当前点的反射。 //如果前一个命令不存在,或者前一个命令不是二次贝塞尔曲线命令或平滑的二次贝塞尔曲线命令,则此控制点就是当前点。 case "t": case "T": { curXY.x = double.Parse(commands[i + 1]); curXY.y = double.Parse(commands[i + 2]); if (commands[i] == "t") { curXY += lastXY; } path.curve3(curXY.x, curXY.y); i += 2; hasCurves = true; } break; case "z": case "Z": { curXY = lastXY; // value not used this is to remove an error. path.ClosePolygon(); // svg fonts are stored cw and agg expects its shapes to be ccw. cw shapes are holes. // We stored the position of the start of this polygon, no we flip it as we colse it. //path.invert_polygon(0); } break; case "\r": { curXY = lastXY; // value not used this is to remove an error. } break; } lastXY = curXY; } if (hasCurves == true) return new FlattenCurves(path); return path; }
private void render_gpc(Graphics2D graphics2D) { switch (m_polygons.SelectedIndex) { case 0: { //------------------------------------ // Two simple paths // PathStorage ps1 = new PathStorage(); PathStorage ps2 = new PathStorage(); double x = m_x - Width / 2 + 100; double y = m_y - Height / 2 + 100; ps1.MoveTo(x + 140, y + 145); ps1.LineTo(x + 225, y + 44); ps1.LineTo(x + 296, y + 219); ps1.ClosePolygon(); ps1.LineTo(x + 226, y + 289); ps1.LineTo(x + 82, y + 292); ps1.MoveTo(x + 220, y + 222); ps1.LineTo(x + 363, y + 249); ps1.LineTo(x + 265, y + 331); ps1.MoveTo(x + 242, y + 243); ps1.LineTo(x + 268, y + 309); ps1.LineTo(x + 325, y + 261); ps1.MoveTo(x + 259, y + 259); ps1.LineTo(x + 273, y + 288); ps1.LineTo(x + 298, y + 266); ps2.MoveTo(100 + 32, 100 + 77); ps2.LineTo(100 + 473, 100 + 263); ps2.LineTo(100 + 351, 100 + 290); ps2.LineTo(100 + 354, 100 + 374); graphics2D.Render(ps1, new RGBA_Floats(0, 0, 0, 0.1).GetAsRGBA_Bytes()); graphics2D.Render(ps2, new RGBA_Floats(0, 0.6, 0, 0.1).GetAsRGBA_Bytes()); CreateAndRenderCombined(graphics2D, ps1, ps2); } break; case 1: { //------------------------------------ // Closed stroke // PathStorage ps1 = new PathStorage(); PathStorage ps2 = new PathStorage(); Stroke stroke = new Stroke(ps2); stroke.width(10.0); double x = m_x - Width / 2 + 100; double y = m_y - Height / 2 + 100; ps1.MoveTo(x + 140, y + 145); ps1.LineTo(x + 225, y + 44); ps1.LineTo(x + 296, y + 219); ps1.ClosePolygon(); ps1.LineTo(x + 226, y + 289); ps1.LineTo(x + 82, y + 292); ps1.MoveTo(x + 220 - 50, y + 222); ps1.LineTo(x + 265 - 50, y + 331); ps1.LineTo(x + 363 - 50, y + 249); ps1.close_polygon(ShapePath.FlagsAndCommand.FlagCCW); ps2.MoveTo(100 + 32, 100 + 77); ps2.LineTo(100 + 473, 100 + 263); ps2.LineTo(100 + 351, 100 + 290); ps2.LineTo(100 + 354, 100 + 374); ps2.ClosePolygon(); graphics2D.Render(ps1, new RGBA_Floats(0, 0, 0, 0.1).GetAsRGBA_Bytes()); graphics2D.Render(stroke, new RGBA_Floats(0, 0.6, 0, 0.1).GetAsRGBA_Bytes()); CreateAndRenderCombined(graphics2D, ps1, stroke); } break; case 2: { //------------------------------------ // Great Britain and Arrows // PathStorage gb_poly = new PathStorage(); PathStorage arrows = new PathStorage(); GreatBritanPathStorage.Make(gb_poly); make_arrows(arrows); Affine mtx1 = Affine.NewIdentity(); Affine mtx2 = Affine.NewIdentity(); mtx1 *= Affine.NewTranslation(-1150, -1150); mtx1 *= Affine.NewScaling(2.0); mtx2 = mtx1; mtx2 *= Affine.NewTranslation(m_x - Width / 2, m_y - Height / 2); VertexSourceApplyTransform trans_gb_poly = new VertexSourceApplyTransform(gb_poly, mtx1); VertexSourceApplyTransform trans_arrows = new VertexSourceApplyTransform(arrows, mtx2); graphics2D.Render(trans_gb_poly, new RGBA_Floats(0.5, 0.5, 0, 0.1).GetAsRGBA_Bytes()); Stroke stroke_gb_poly = new Stroke(trans_gb_poly); stroke_gb_poly.Width = 0.1; graphics2D.Render(stroke_gb_poly, new RGBA_Floats(0, 0, 0).GetAsRGBA_Bytes()); graphics2D.Render(trans_arrows, new RGBA_Floats(0.0, 0.5, 0.5, 0.1).GetAsRGBA_Bytes()); CreateAndRenderCombined(graphics2D, trans_gb_poly, trans_arrows); } break; case 3: { //------------------------------------ // Great Britain and a Spiral // spiral sp = new spiral(m_x, m_y, 10, 150, 30, 0.0); Stroke stroke = new Stroke(sp); stroke.width(15.0); PathStorage gb_poly = new PathStorage(); GreatBritanPathStorage.Make(gb_poly); Affine mtx = Affine.NewIdentity(); ; mtx *= Affine.NewTranslation(-1150, -1150); mtx *= Affine.NewScaling(2.0); VertexSourceApplyTransform trans_gb_poly = new VertexSourceApplyTransform(gb_poly, mtx); graphics2D.Render(trans_gb_poly, new RGBA_Floats(0.5, 0.5, 0, 0.1).GetAsRGBA_Bytes()); Stroke stroke_gb_poly = new Stroke(trans_gb_poly); stroke_gb_poly.width(0.1); graphics2D.Render(stroke_gb_poly, new RGBA_Floats(0, 0, 0).GetAsRGBA_Bytes()); graphics2D.Render(stroke, new RGBA_Floats(0.0, 0.5, 0.5, 0.1).GetAsRGBA_Bytes()); CreateAndRenderCombined(graphics2D, trans_gb_poly, stroke); } break; case 4: { //------------------------------------ // Spiral and glyph // spiral sp = new spiral(m_x, m_y, 10, 150, 30, 0.0); Stroke stroke = new Stroke(sp); stroke.width(15.0); PathStorage glyph = new PathStorage(); glyph.MoveTo(28.47, 6.45); glyph.curve3(21.58, 1.12, 19.82, 0.29); glyph.curve3(17.19, -0.93, 14.21, -0.93); glyph.curve3(9.57, -0.93, 6.57, 2.25); glyph.curve3(3.56, 5.42, 3.56, 10.60); glyph.curve3(3.56, 13.87, 5.03, 16.26); glyph.curve3(7.03, 19.58, 11.99, 22.51); glyph.curve3(16.94, 25.44, 28.47, 29.64); glyph.LineTo(28.47, 31.40); glyph.curve3(28.47, 38.09, 26.34, 40.58); glyph.curve3(24.22, 43.07, 20.17, 43.07); glyph.curve3(17.09, 43.07, 15.28, 41.41); glyph.curve3(13.43, 39.75, 13.43, 37.60); glyph.LineTo(13.53, 34.77); glyph.curve3(13.53, 32.52, 12.38, 31.30); glyph.curve3(11.23, 30.08, 9.38, 30.08); glyph.curve3(7.57, 30.08, 6.42, 31.35); glyph.curve3(5.27, 32.62, 5.27, 34.81); glyph.curve3(5.27, 39.01, 9.57, 42.53); glyph.curve3(13.87, 46.04, 21.63, 46.04); glyph.curve3(27.59, 46.04, 31.40, 44.04); glyph.curve3(34.28, 42.53, 35.64, 39.31); glyph.curve3(36.52, 37.21, 36.52, 30.71); glyph.LineTo(36.52, 15.53); glyph.curve3(36.52, 9.13, 36.77, 7.69); glyph.curve3(37.01, 6.25, 37.57, 5.76); glyph.curve3(38.13, 5.27, 38.87, 5.27); glyph.curve3(39.65, 5.27, 40.23, 5.62); glyph.curve3(41.26, 6.25, 44.19, 9.18); glyph.LineTo(44.19, 6.45); glyph.curve3(38.72, -0.88, 33.74, -0.88); glyph.curve3(31.35, -0.88, 29.93, 0.78); glyph.curve3(28.52, 2.44, 28.47, 6.45); glyph.ClosePolygon(); glyph.MoveTo(28.47, 9.62); glyph.LineTo(28.47, 26.66); glyph.curve3(21.09, 23.73, 18.95, 22.51); glyph.curve3(15.09, 20.36, 13.43, 18.02); glyph.curve3(11.77, 15.67, 11.77, 12.89); glyph.curve3(11.77, 9.38, 13.87, 7.06); glyph.curve3(15.97, 4.74, 18.70, 4.74); glyph.curve3(22.41, 4.74, 28.47, 9.62); glyph.ClosePolygon(); Affine mtx = Affine.NewIdentity(); mtx *= Affine.NewScaling(4.0); mtx *= Affine.NewTranslation(220, 200); VertexSourceApplyTransform trans = new VertexSourceApplyTransform(glyph, mtx); FlattenCurves curve = new FlattenCurves(trans); CreateAndRenderCombined(graphics2D, stroke, curve); graphics2D.Render(stroke, new RGBA_Floats(0, 0, 0, 0.1).GetAsRGBA_Bytes()); graphics2D.Render(curve, new RGBA_Floats(0, 0.6, 0, 0.1).GetAsRGBA_Bytes()); } break; } }
private void RenderPolygonToPathAgainst(Graphics2D graphics2D) { IVertexSource pathToUse = null; switch (shapeTypeRadioGroup.SelectedIndex) { case 0:// simple polygon map { PathStorage ps1 = new PathStorage(); ps1.MoveTo(85, 417); ps1.LineTo(338, 428); ps1.LineTo(344, 325); ps1.LineTo(399, 324); ps1.LineTo(400, 421); ps1.LineTo(644, 415); ps1.LineTo(664, 75); ps1.LineTo(98, 81); ps1.ClosePolygon(); ps1.MoveTo(343, 290); ps1.LineTo(159, 235); ps1.LineTo(154, 162); ps1.LineTo(340, 114); ps1.ClosePolygon(); ps1.MoveTo(406, 121); ps1.LineTo(587, 158); ps1.LineTo(591, 236); ps1.LineTo(404, 291); ps1.ClosePolygon(); pathToUse = ps1; } break; case 1: // multiple pegs { PathStorage ps2 = new PathStorage(); double x = 0; double y = 0; ps2.MoveTo(100 + 32, 100 + 77); ps2.LineTo(100 + 473, 100 + 263); ps2.LineTo(100 + 351, 100 + 290); ps2.LineTo(100 + 354, 100 + 374); pathToUse = ps2; } break; case 2: { // circle holes PathStorage ps1 = new PathStorage(); double x = 0; double y = 0; ps1.MoveTo(x + 140, y + 145); ps1.LineTo(x + 225, y + 44); ps1.LineTo(x + 296, y + 219); ps1.ClosePolygon(); ps1.LineTo(x + 226, y + 289); ps1.LineTo(x + 82, y + 292); ps1.ClosePolygon(); ps1.MoveTo(x + 220 - 50, y + 222); ps1.LineTo(x + 265 - 50, y + 331); ps1.LineTo(x + 363 - 50, y + 249); ps1.ClosePolygon(); pathToUse = ps1; } break; case 3: // Great Britain { PathStorage gb_poly = new PathStorage(); GreatBritanPathStorage.Make(gb_poly); Affine mtx1 = Affine.NewIdentity(); Affine mtx2 = Affine.NewIdentity(); mtx1 *= Affine.NewTranslation(-1150, -1150); mtx1 *= Affine.NewScaling(2.0); mtx2 = mtx1; mtx2 *= Affine.NewTranslation(Width / 2, Height / 2); VertexSourceApplyTransform trans_gb_poly = new VertexSourceApplyTransform(gb_poly, mtx1); pathToUse = trans_gb_poly; } break; case 4: // Arrows { PathStorage arrows = new PathStorage(); make_arrows(arrows); Affine mtx1 = Affine.NewIdentity(); mtx1 *= Affine.NewTranslation(-1150, -1150); mtx1 *= Affine.NewScaling(2.0); VertexSourceApplyTransform trans_arrows = new VertexSourceApplyTransform(arrows, mtx1); pathToUse = trans_arrows; } break; case 5: // Spiral { spiral sp = new spiral(Width / 2, Height / 2, 10, 150, 30, 0.0); Stroke stroke = new Stroke(sp); stroke.width(15.0); Affine mtx = Affine.NewIdentity(); ; mtx *= Affine.NewTranslation(-1150, -1150); mtx *= Affine.NewScaling(2.0); pathToUse = stroke; } break; case 6: // Glyph { //------------------------------------ // Spiral and glyph // PathStorage glyph = new PathStorage(); glyph.MoveTo(28.47, 6.45); glyph.curve3(21.58, 1.12, 19.82, 0.29); glyph.curve3(17.19, -0.93, 14.21, -0.93); glyph.curve3(9.57, -0.93, 6.57, 2.25); glyph.curve3(3.56, 5.42, 3.56, 10.60); glyph.curve3(3.56, 13.87, 5.03, 16.26); glyph.curve3(7.03, 19.58, 11.99, 22.51); glyph.curve3(16.94, 25.44, 28.47, 29.64); glyph.LineTo(28.47, 31.40); glyph.curve3(28.47, 38.09, 26.34, 40.58); glyph.curve3(24.22, 43.07, 20.17, 43.07); glyph.curve3(17.09, 43.07, 15.28, 41.41); glyph.curve3(13.43, 39.75, 13.43, 37.60); glyph.LineTo(13.53, 34.77); glyph.curve3(13.53, 32.52, 12.38, 31.30); glyph.curve3(11.23, 30.08, 9.38, 30.08); glyph.curve3(7.57, 30.08, 6.42, 31.35); glyph.curve3(5.27, 32.62, 5.27, 34.81); glyph.curve3(5.27, 39.01, 9.57, 42.53); glyph.curve3(13.87, 46.04, 21.63, 46.04); glyph.curve3(27.59, 46.04, 31.40, 44.04); glyph.curve3(34.28, 42.53, 35.64, 39.31); glyph.curve3(36.52, 37.21, 36.52, 30.71); glyph.LineTo(36.52, 15.53); glyph.curve3(36.52, 9.13, 36.77, 7.69); glyph.curve3(37.01, 6.25, 37.57, 5.76); glyph.curve3(38.13, 5.27, 38.87, 5.27); glyph.curve3(39.65, 5.27, 40.23, 5.62); glyph.curve3(41.26, 6.25, 44.19, 9.18); glyph.LineTo(44.19, 6.45); glyph.curve3(38.72, -0.88, 33.74, -0.88); glyph.curve3(31.35, -0.88, 29.93, 0.78); glyph.curve3(28.52, 2.44, 28.47, 6.45); glyph.ClosePolygon(); glyph.MoveTo(28.47, 9.62); glyph.LineTo(28.47, 26.66); glyph.curve3(21.09, 23.73, 18.95, 22.51); glyph.curve3(15.09, 20.36, 13.43, 18.02); glyph.curve3(11.77, 15.67, 11.77, 12.89); glyph.curve3(11.77, 9.38, 13.87, 7.06); glyph.curve3(15.97, 4.74, 18.70, 4.74); glyph.curve3(22.41, 4.74, 28.47, 9.62); glyph.ClosePolygon(); Affine mtx = Affine.NewIdentity(); mtx *= Affine.NewScaling(4.0); mtx *= Affine.NewTranslation(220, 200); VertexSourceApplyTransform trans = new VertexSourceApplyTransform(glyph, mtx); FlattenCurves curve = new FlattenCurves(trans); pathToUse = curve; } break; } graphics2D.Render(pathToUse, fillColor); PathStorage travelLine = new PathStorage(); travelLine.MoveTo(lineStart); travelLine.LineTo(mousePosition); Polygons polygonsToPathAround = VertexSourceToClipperPolygons.CreatePolygons(pathToUse, 1); polygonsToPathAround = FixWinding(polygonsToPathAround); Polygons travelPolysLine = VertexSourceToClipperPolygons.CreatePolygons(travelLine, 1); CreateAndRenderPathing(graphics2D, polygonsToPathAround, travelPolysLine); }