将坐标集绘制为像素,以便它们相互缩放
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
等等。现在它在底部稍微偏离了一点点;坏小子我 ;-)
所以我有一个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
等等。现在它在底部稍微偏离了一点点;坏小子我 ;-)