On 8 May 2020, at 13:58, Gerben Wierda
wrote: On 8 May 2020, at 00:46, ntg@scorecrow.com wrote:
On 7 May 2020, at 20:28, Gerben Wierda
wrote: I have a METAPOST algorithm that splits a path at a certain time in two, does something with both ends (not the ends where they were split) and then rejoins them.
In very rare cases this crashes, because the subpath doesn’t work as expected.
firstPart := subpath (0,halfWayTime) of workingConn; secondPart := subpath (halfWayTime,pathTimeLen) of workingConn;
may sometimes result in something like this:
metapost log > >> Path at line 0: metapost log > (273,-427)..controls (259.50666666666666,-427) and (246.01333333333335,-427) metapost log > ..(232.52000000000001,-427) metapost log > metapost log > >> Path at line 0: metapost log > (232.51999999999998,-427)..controls (161.68000000000001,-427) and (90.840000000 metapost log > 000003,-427) metapost log > ..(20,-427)
As can be seen in these (rare) cases the two calls to subpath result in a different point resulting from both. so, when I later try to rejoin them with & it fails:
metapost log > ! Paths don't touch; '&' will be changed to '..'. metapost log > <to be read again>
Which means subpath doesn’t always exactly do what I expect it to do (and many explanations, but not the official manual) state. Again, this is rare.
I’ve done this to work around it but I wondered if there was a better (reliable) solution
save cutFirstPart; path cutFirstPart; cutFirstPart := firstPart maxcutbefore fromPicOutline; save cutSecondPart; path cutSecondPart; cutSecondPart := secondPart maxcutafter toPicOutline; if ((xpart point 0 of cutSecondPart) <> (xpart point infinity of cutFirstPart)) or ((ypart point 0 of cutSecondPart) <> (ypart point infinity of cutFirstPart)): resultConn := cutFirstPart--cutSecondPart; else: resultConn := cutFirstPart & cutSecondPart; fi
A crude test of
path pb; pb:=(5.5cm,0cm)--(5.5cm,0cm)--(10.5cm,0cm); draw pb;
gives no errors so why not just join using -- all the time and save the test?
Because the double exact points are also creating (different) problems in my algorithm as they make the path have 'no direction' at that point (direction is (0,0).
You can save extracting the xparts and yparts by using direct subtraction of pairs and comparing with (0,0) like this: \starttext \startMPcode path cutFirstPart,cutSecondPart; cutFirstPart := (0,0) -- (232.52000000000001,-427); cutSecondPart := (232.51999999999998,-427) -- (999,-427); %cutFirstPart := (0,0) -- (232.52000000000001,-427); %cutSecondPart := (232.52000000000001,-427) -- (999,-427); if (point infinity of cutFirstPart) - (point 0 of cutSecondPart) = (0,0) : label("same", (1cm,1cm)) else : label("different", (1cm,1cm)) fi; \stopMPcode \stoptext *Except* that the example doesn't work with floats that are so close. Changing 232.52_etc to 332.52_etc works as expected. I'm hoping that this is a "feature" of the parser reading in the example at a lower precision than the number of decimals provided. For your code, where the different values are created by calculation, the two pairs should be recognised as different. -- Bruce Horrocks Hampshire, UK