将坐标集绘制为像素,以便它们相互缩放

Drawing sets of coordinates to pixels so they mutually scale

所以我有一个List<object>两点的经纬度坐标,我需要连接它们之间的线。诀窍是在面板中显示所有线条,以便它们在面板尺寸内缩放(转换坐标数以匹配像素),我几乎明白了。但是我对一些未知问题感到困惑。代码是:

int canvasWidth = panel1.Width,
            canvasHeight = panel1.Height;

        var minX1 = tockeKoordinate.Min(x => x.startX);
        var minX2 = tockeKoordinate.Min(x => x.endX);
        var minX = Math.Min(minX1, minX2);

        var maxX1 = tockeKoordinate.Max(x => x.startX);
        var maxX2 = tockeKoordinate.Max(x => x.endX);
        var maxX = Math.Max(maxX1, maxX2);

        var maxY1 = tockeKoordinate.Max(x => x.startY);
        var maxY2 = tockeKoordinate.Max(x => x.endY);
        var maxY = Math.Max(maxY1, maxY2);

        var minY1 = tockeKoordinate.Min(x => x.startY);
        var minY2 = tockeKoordinate.Min(x => x.endY);
        var minY = Math.Min(minY1, minY2);


        double coordinatesWidth = Math.Abs(maxX - minX),
               coordinatesHeight = Math.Abs(maxY - minY);

        float coefWidth = (float)coordinatesWidth / canvasWidth,
              coefHeight = (float)coordinatesHeight / canvasHeight;

基本上我检查 List 的最小和最大 XY 坐标,所以我知道极值是多少。然后我使用一个系数值重新计算以像素为单位的坐标,以便在面板内。当我使用这个时:

 drawLine(Math.Abs((float)(line.startX - minX) / coefWidth),
                Math.Abs((float)(line.startY - minY) / coefHeight),
                Math.Abs((float)(line.endX - maxX) / coefWidth),
                Math.Abs((float)(line.endY - maxY) / coefHeight));

位于 foreach 循环中,循环遍历 List 中的所有元素。 drawline()方法如下:

private void drawLine(float startX, float startY, float endX, float endY)
    {

        PointF[] points =
        {
            new PointF(startX, startY),
            new PointF(endX, endY),
        };
        g.DrawLine(myPen, points[0], points[1]);
    }

当所有这些放在一起时,我得到了这张照片:

我知道 "lines" 应该连接起来并形成形状,在这种情况下,它们代表郊区的道路。 我认为它将每个坐标集都视为唯一的坐标集,然后将其缩放到面板尺寸。实际上它应该参考所有其他坐标

来缩放它

它应该 "zoom" 它们出来并相互连接,因为这是我定义面板尺寸和其他所有内容的方式。

编辑:ToW 的解决方案成功了,将这行代码更改为使用我的列表:

foreach (var line in tockeKoordinate)
        {

            gp.AddLine((float)(line.startX), (float)(line.startY), (float)(line.endX), (float)(line.endY));
gp.CloseFigure();

        }

正常运行时的最终结果:

据我所知,最好的选择是将所有这些行添加到 GraphicsPath

完成后,您可以查看其边界矩形并将其与您的 Panel 提供的大小进行比较。

然后您可以计算要绘制的 Graphics 对象的比例以及平移。

最后用 Graphics.DrawPath 画线。

你这边只有 2 个师:-)

这是一个例子:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics G = e.Graphics;
    Random R = new Random(13);
    GraphicsPath gp = new GraphicsPath();
    for (int i = 0; i < 23; i++)
    {
        gp.AddLine(R.Next(1234), R.Next(1234), R.Next(1234), R.Next(1234));
        gp.CloseFigure();  // disconnect lines
    }
    RectangleF rect = gp.GetBounds();

    float scale = Math.Min(1f * panel1.Width / rect.Width, 
                           1f * panel1.Height / rect.Height);


    using (Pen penUnscaled = new Pen(Color.Blue, 4f))
    using (Pen penScaled = new Pen(Color.Red, 4f))
    {
        G.Clear(Color.White);
        G.DrawPath(penUnscaled, gp);
        G.ScaleTransform(scale, scale);
        G.TranslateTransform(-rect.X, -rect.Y);
        G.DrawPath(penScaled, gp);
    }
}

一些注意事项:

  • 蓝线不适合面板
  • 红线按比例缩小以适合
  • Pen 与图形的其余部分一起缩放,但不会低于 1f。
  • 要创建连接线,请添加 PointF[] 或更方便的 List<PointF>.ToArray().
  • 我真的应该使用 panel1.ClientSize.Width 而不是 panel1.Width 等等。现在它在底部稍微偏离了一点点;坏小子我 ;-)