howardjones / network-weathermap

Network Weathermap draws diagrams from data
http://www.network-weathermap.com/
MIT License
425 stars 95 forks source link

Some SPLITPOS values for angled vias can crash weathermap (parallel vectors) #205

Closed howardjones closed 3 years ago

howardjones commented 5 years ago

This config crashes weathermap with an exception while trying to find the crossing point of two parallel lines. The same thing does not happen if you move both points 4000 pixels left (X is 370 and 30) instead. It is also fine if SPLITPOS is 50.

WIDTH 4640
HEIGHT 3100

# regular NODEs:
NODE node111111111111111111111111111
    LABEL node111111111111111111111111111
    POSITION 4370 100

NODE node2
    LABEL node2
    POSITION 4030 2400

LINK node111111111111111111111111111-node2
    WIDTH 2
    BWLABEL bits
    VIASTYLE angled
    SPLITPOS 19
    NODES node111111111111111111111111111:W10 node2:E
    VIA node2 320 0
howardjones commented 5 years ago

Failure is PHP Fatal error: Uncaught Weathermap\Core\WeathermapInternalFail: ParallelLinesNeverCross in /home/howie/Work/network-weathermap/lib/Weathermap/Core/Line.php:56

While finding $crossingPoint1, which is where $line1 and $line2 cross - the outside corner of the link as it goes around a VIA corner. This should never be parallel, as the spine is simplified to remove colinear points after it is split into two spines (one for each direction, split at SPLITPOS).

image

howardjones commented 5 years ago

If SPLITPOS is close to one end, you can end up with a spine of only two points after the split is done. Spine::splitAtDistance() needs to interpolate a middle point if there are only two. (Good news is that if there are only two, it'll always be a simple linear interpolation)

howardjones commented 5 years ago

Also, when coordinates are large, getTriangleArea() and simplify() start to get too fussy, and not simplify points that they should.