为什么 Graphics.DrawLine 画出的形状是楔形?

6
我正在试图以一系列简单的线条形式绘制公交路线。没有花哨的东西。但是,我得到的不是线条,而是楔形图。一开始,我对此还算满意,因为楔形图有点像箭头,总是指向第二个点。但现在我想改进外观,楔形图成了一个大问题。
我怀疑这是由于图形变换造成的浮点数问题(lat/lons被输入,变换将它们转换为位图上的x/y坐标[假设lat/lon是欧几里得距离,对我的目的足够准确],所以缩放是几个数量级)。
截图: 'Wedge' line overlayed over a road 实际上,看起来线条被分成了两个三角形,但只有一个被绘制了出来。
相关代码(注意:绘制是异步进行的,这就是为什么我要创建一个位图的原因):
'-- Creating the transform --'
Dim bitmap = New Bitmap(Math.Max(1, PictureBox1.Width), Math.Max(1, PictureBox1.Height))

Dim g = Graphics.FromImage(bitmap)
g.TranslateTransform(0, bitmap.Height)
g.ScaleTransform(1, -1)
g.ScaleTransform(CSng(bitmap.Width) / (maxLon - minLon), CSng(bitmap.Height) / (maxLat - minLat))
g.TranslateTransform(-minLon, -minLat)

'-- Drawing the lines (in a method called asynchronously) --'
using pen = New Pen(Brushes.Black, 0.0001)
Dim shapes = busData.TripsInGroup(tripGroup.Value).
             Select(Function(e) e.Shape).
             Distinct()
For Each shape In shapes
    For i = 0 To shape.Points.Count - 2
        Dim e1 = shape.Points(i)
        Dim e2 = shape.Points(i + 1)
        Dim p1 = New PointF(CSng(e1.Longitude), CSng(e1.Latitude))
        Dim p2 = New PointF(CSng(e2.Longitude), CSng(e2.Latitude))
        g.DrawLine(pen, p1, p2)
    Next
Next

示例值:

cenLat = 44.657176
cenLon = -63.549471
spnLat = 0.071921
spnLon = 0.179729
minLat = cenLat - spnLat / 2
maxLat = cenLat + spnLat / 2
minLon = cenLon - spnLon / 2
maxLon = cenLon + spnLon / 2
shpts = {(Lat: 44.6518683235, Lon: -63.5930836628), 
         (Lat: 44.6512537117, Lon: -63.5927528307), 
         (Lat: 44.6508013753, Lon: -63.5924572976), 
         (Lat: 44.6503312812, Lon: -63.5921923044), 
         (Lat: 44.6503312812, Lon: -63.5921923044), 
         (Lat: 44.6502137576, Lon: -63.5921260568), 
         (Lat: 44.6495810455, Lon: -63.5917829189), 
         (Lat: 44.648893839, Lon: -63.5913776026), 
         (Lat: 44.6485468163, Lon: -63.5911976944), 
         (Lat: 44.6485468163, Lon: -63.5911976944), 
         (Lat: 44.6475084762, Lon: -63.5906617219), 
         (Lat: 44.6475084762, Lon: -63.5906617219)}

笔记和发现:

  • 使用DrawLines而不是DrawLine解决了问题(但为什么?)
  • 增加画笔的粗细可以解决问题(但线条太粗了)
  • 缩小视窗(减小经纬度视图窗口)最终可以解决问题(但我想要放大!)

1
把笔弄弄,特别是盖子。 - Hans Passant
笔尖?为了适应变换,笔的厚度相当细,但除此之外都很正常。 - Craig Gidney
有趣。将线条厚度增加10倍似乎解决了问题(但使线条变得太粗)。现在我还注意到,当我用原始厚度缩小时,可以看到它会切换到适当的线条,因为它们变得非常小。 - Craig Gidney
有趣。DrawLines 运行良好。它将成为一个不错的解决方法,但 DrawLine 的问题仍然很有趣。 - Craig Gidney
1
问题在于您的坐标精度不足。即使浮点数具有足够的精度,但内部绘图算法却更少。 - Gabe
显示剩余2条评论
2个回答

3

我遇到了同样的问题,并偶然发现了这个帖子。与OP不同,我发现DrawLines并没有解决问题,并且遇到了与DrawLine相同的问题。

Gabe说得对,问题在于内部绘图算法的精度。

我通过将纬度/经度值放大10倍(如果你需要更多缩放,可能需要放大更多)来解决了这个问题,在传递给任何绘图算法之前进行了放大。


2

自我回答:

通过使用DrawLines而不是DrawLine来解决此问题。由于某种原因,DrawLines没有这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接