Why does Graphics.DrawLine draw a wedge shape?

I am trying to draw a bus route as a simple sequence of lines. Nothing special. But instead of lines, I get wedges. Initially, I was fine with this, because the wedge sortings are similar to arrows and are always facing the second point. But now I want to improve the look, and wedges are becoming a big problem.

My suspicion is something like a floating-point problem due to a graphical conversion (lat / lons are cast, and the conversion turns them into x / y on a bitmap [assuming lat / lon is Euclidean, accurate enough for my purposes] , therefore scaling by several orders of magnitude).

Screenshot:

'Wedge' line overlayed over a road

It actually looks like the line was divided into two triangles, but only one of them was drawn.

Corresponding code (note: the drawing is executed asynchronously, so I am creating a bitmap):

'-- 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 

Example values:

 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)} 

Notes and discoveries:

  • Using DrawLines instead of DrawLine solves the problem (but why?)
  • Increasing the thickness of the pen makes the problem go away (but the lines are too thick)
  • Zooming out (enlarging the lat / lon viewport) makes the problem go away in the end (but I want to zoom in!).
+6
source share
2 answers

I had the same problem and stumbled upon this thread. Unlike the OP, I found that DrawLines does not solve the problem and suffers from the same problem as DrawLine.

Gabe is right because the problem is related to the accuracy of internal drawing algorithms.

I solved the problem by increasing the lat / long values ​​10 times (although if you do more scaling, you may need to zoom in) before passing them to any drawing algorithm.

+3
source

Self-answer:

Workaround with DrawLines instead of DrawLine. DrawLines for some reason does not have this problem.

+2
source

Source: https://habr.com/ru/post/900787/


All Articles