绘制围绕给定路径的路径

ste*_*wpf 13 c# graphics pdfsharp

*更新*

使用Clipper库找到解决方案.解决方案添加为答案.不过,欢迎新的/更好/更简单的想法!


给出这样的路径:

原始的黑色路径

我想创建一条围绕此路径的路径,给定距离,例如1厘米.下面的草图演示了 - 红色路径围绕黑色路径,距离为1厘米.

黑色路径被一条距离为1厘米的红色路径包围

如何使用PDFSharp以通用方式完成此操作?(意思是我想最终用PDFSharp绘制它,我不在乎计算的位置)以下是黑色路径的代码:

// helper for easily getting an XPoint in centimeters
private XPoint cmPoint(double x, double y)
{
    return new XPoint(
        XUnit.FromCentimeter(x),
        XUnit.FromCentimeter(y)
        );
}


// the path to be drawn
private XGraphicsPath getMyPath()
{
    XGraphicsPath path = new XGraphicsPath();

    XPoint[] points = new XPoint[3];
    points[0] = cmPoint(0, 0);
    points[1] = cmPoint(5, 2);
    points[2] = cmPoint(10,0);

    path.AddCurve(points);
    path.AddLine(cmPoint(10, 0), cmPoint(10, 10));
    path.AddLine(cmPoint(10, 10), cmPoint(0, 10));
    path.CloseFigure(); 

    return path;
}


// generate the PDF file
private void button3_Click(object sender, RoutedEventArgs e)
{
    // Create a temporary file
    string filename = String.Format("{0}_tempfile.pdf", Guid.NewGuid().ToString("D").ToUpper());

    XPen penBlack = new XPen(XColors.Black, 1);
    XPen penRed = new XPen(XColors.Red, 1);

    PdfDocument pdfDocument = new PdfDocument();

    PdfPage page = pdfDocument.AddPage();
    page.Size = PdfSharp.PageSize.A1;

    XGraphics gfx = XGraphics.FromPdfPage(page);

    //give us some space to the left and top
    gfx.TranslateTransform(XUnit.FromCentimeter(3), XUnit.FromCentimeter(3));

    // draw the desired path
    gfx.DrawPath(penBlack, getMyPath());


    // Save the pdfDocument...
    pdfDocument.Save(filename);
    // ...and start a viewer
    Process.Start(filename);
}
Run Code Online (Sandbox Code Playgroud)

感谢您对此主题的任何帮助!

Art*_*aca 9

您可以使用Widen()函数,该函数将曲线替换为包含在指定笔绘制路径时填充的区域的曲线,并为路径添加其他轮廓.

此函数作为参数a接收XPen,因此您可以XPen使用所需的偏移量作为宽度创建此函数,并且将以恒定距离(笔的宽度)添加外部路径.

XGraphicsPathclass实际上是一个包装器System.Drawing.Drawing2D.GraphicsPath,所以你可以使用Widen()函数XGraphicsPath,获取内部对象并使用GraphicsPathIterator类迭代它以获得添加的路径.

这种方法可以完成这项工作:

public XGraphicsPath GetSurroundPath(XGraphicsPath path, double width)
{
    XGraphicsPath container = new XGraphicsPath();

    container.StartFigure();
    container.AddPath(path, false);
    container.CloseFigure();

    var penOffset = new XPen(XColors.Black, width);

    container.StartFigure();
    container.Widen(penOffset);
    container.CloseFigure();

    var iterator = new GraphicsPathIterator(container.Internals.GdiPath);

    bool isClosed;
    var outline = new XGraphicsPath();
    iterator.NextSubpath(outline.Internals.GdiPath, out isClosed);

    return outline;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用过载处理曲线中的平坦度Widen(XPen pen, XMatrix matrix, double flatness).执行此调用会container.Widen(penOffset, XMatrix.Identity, 0.05);产生更圆的边缘.

然后使用此函数绘制外部路径:

string filename = String.Format("{0}_tempfile.pdf", Guid.NewGuid().ToString("D").ToUpper());

XPen penBlack = new XPen(XColors.Black, 1);
XPen penRed = new XPen(XColors.Red, 1);

PdfDocument pdfDocument = new PdfDocument();

PdfPage page = pdfDocument.AddPage();
page.Size = PdfSharp.PageSize.A1;

XGraphics gfx = XGraphics.FromPdfPage(page);

//give us some space to the left and top
gfx.TranslateTransform(XUnit.FromCentimeter(3), XUnit.FromCentimeter(3));

var path = getMyPath();

// draw the desired path
gfx.DrawPath(penBlack, path);
gfx.DrawPath(penRed, GetSurroundPath(path, XUnit.FromCentimeter(1).Point));

// Save the pdfDocument...
pdfDocument.Save(filename);
// ...and start a viewer
Process.Start(filename);
Run Code Online (Sandbox Code Playgroud)

这就是你得到的:

在此输入图像描述

另一种方法可能是使用反射来检索内部Pen输入XPen和设置CompoundArray属性.这允许您绘制平行线和空格.使用此属性,您可以执行以下操作:

在此输入图像描述

但问题是你只能使用一种颜色,无论如何这只是一个想法,我还没试过 PDFsharp

此外,您应该搜索偏移折线曲线偏移多边形算法.