It is common practice to extract contour data using 'set table' with splot
and reuse it in another plot.
If the generated contour is simple, it is output as a single continuous curve. However, in the case of more complex contours exceeding about 100 points, the output is split into several segmented curves.
Here is a simple example:
set term wxt
f(x,y) = x**2 + y**2
set xrange [-2:2]
set yrange [-2:2]
set zrange [0:4]
set isotropic
set xyplane 0
set samples 85
set isosamples 85
set table $contour
unset surface
set contour surface
set cntrparam level discrete 3
splot f(x,y) with lines
unset contour
set surface
unset table
set title "contour as line"
splot f(x,y) with lines notitle lc "#c0c0c0c0", \
$contour using 1:2:3:(column(-1)+1) with lines lc variable lw 3 notitle
pause -1 "Hit <cr> to continue"
set title "contour as filled polygon"
splot $contour with polygons fc 'pink' notitle
pause -1 "Hit <cr> to continue"
In this example, the contour line stored in the $contour
datablock consists of approximately 300 points but is split into three separate curves of up to 100 points each. The larger the samples
and isosamples
values, the more likely it is that curves will be divided. Additionally, applying smoothing methods such as cubicspline
can increase the number of segments, exacerbating the issue.
Attached patch is a trial one to preserve the continuity of contour lines.
Specifically, in end_crnt_cntr()
, it checks whether the last curve in the contour_list
is continuous with the new curve to be added. If they are continuous, it merges them into a single curve; otherwise, it treats the new curve as a separate one.
I think you may be overlooking a simpler explanation, and simpler fix, for the discontinuities seen in this example.
The 100 point per contour segment is a defined constant. In your example case bumping this up to 1000 points removes the discontinuities. One possible fix is to make this a limit that the user can set.
I am not sure, but I think that limit is there because in the old days PostScript output (and later other vector outputs like SVG) behaved poorly if there were long sequences of relative move/draw segments. Breaking after each 100 pts forced an absolute coordinate pair to be written, limiting the build-up of errors. The PostScript terminal itself limits such a sequence to 250 relative segments, but whoever wrote the contouring was more conservative and set the limit at 100. In version 5 development various terminals were modified to keep more precision, so probably this is less of an issue now than it used to be.
Fixed by commit 83cd1370
Instead of building up a contour line using a fixed-length array of 100 points, dynamically allocate additional points as needed.
Thanks for committing an improved implementation — much appreciated!