|
|
"Bald Eagle" <cre### [at] netscapenet> wrote:
> So, I'm trying to convert some online code to SDL,
>
> ( https://github.com/xmdi/CAD-from-Scratch/blob/main/016/geom.c )
>
> and the conditions in the while statement
> #while( j >= 0 & bins[j] > key)
> don't protect against j being negative.
>
> "C:\Users\Mini\Documents\POV-Ray\v3.8-beta\scenes\DelaunayTriangulateTest1.pov"
> line 226: Parse Error: Negative subscript
>
> Render failed
>
> Probably because they're collected in one line / statement and are therefore all
> evaluated together, and the while loop doesn't terminate until that expression
> is fully evaluated.
You may want to have a look at these questions, answers and comments::
What is "short-circuiting" in C like languages?
https://softwareengineering.stackexchange.com/questions/201896/what-is-short-circuiting-in-c-like-languages
What is short-circuit evaluation in C?
https://stackoverflow.com/questions/45848858/what-is-short-circuit-evaluation-in-c
Is short-circuiting logical operators mandated? And evaluation order?
https://stackoverflow.com/questions/628526/is-short-circuiting-logical-operators-mandated-and-evaluation-order
My opinion is that writing code that depends on short circuiting is
bad practice (i.e. hard to understand and debug - and not so portable,
as you have now experienced).
> I managed to hacktastically bypass / protect against this with some additional
> protective wrappers to the loop, but this doesn't seem like it ought to be
> necessary, or else there ought to be a more elegant way to correct this in SDL.
>
> Unless the while source code has a bug that I've triggered, and _I've broken
> POV-Ray AGAIN_. :\
>
> // sort points by proximity
> #local NbinRows = ceil(pow(numpoints, 0.25));
> #local bins = array [numpoints+1];
>
> #for (i, 0, numpoints)
> #local p = (points[i][1] * NbinRows*0.999); // bin row
> #local q = (points[i][0] * NbinRows*0.999); // bin column
> #if (mod(p, 2))
> #local bins[i] = (p+1) * NbinRows - q;
> #else
> #local bins[i] = p * NbinRows + q + 1;
> #end
> #end
>
> #for (i, 1, numpoints) // insertion sort
> #local key = bins[i];
> #local tempF = array {points[i][0], points[i][1]};
> #local j = i - 1;
> #debug "------------------------------------------------\n"
> #debug concat (" i = ", str (i, 0, 0), "\n")
> #debug concat ("bins[i] = ", str (bins[i], 0, 0), "\n")
> #debug concat ("bins[j] = ", str (bins[j], 0, 0), "\n")
> #if (j > 0)
> #while( j >= 0 & bins[j] > key)
> #local bins[j+1] = bins[j];
> #local points[j+1][0] = points[j][0];
> #local points[j+1][1] = points[j][1];
> #local j = j-1;
>
> #debug concat ("j = ", str (j, 0, 0), "\n")
> #debug concat ("bins[i] = ", str (bins[i], 0, 0), "\n")
> #if (j<0) #break #end
> #end // end while
> #end
>
> #local bins[j+1] = key;
> #local points[j+1][0] = tempF[0];
> #local points[j+1][1] = tempF[1];
> #end
>...
You can try something like this:
(NB: Untested code)
// Sort points by proximity
#local NoOfBinRows = ceil(pow(NoOfPoints, 0.25));
#local Bins = array[NoOfPoints+1];
#for (I, 0, NoOfPoints)
#local P = Points[I][1]*NoOfBinRows*0.999; // bin row
#local Q = Points[I][0]*NoOfBinRows*0.999; // bin column
#local Bins[I] = P*NoOfBinRows + (mod(P, 2) = 0 ? Q + 1 : NoOfBinRows - Q);
#end // for
// Insertion sort
#for (I, 1, NoOfPoints)
#local Key = Bins[I];
#local TempF_0 = Points[I][0];
#local TempF_1 = Points[I][1];
#local J = I - 1;
#local Continue = (Bins[J] > Key);
#while (Continue)
#local Bins[J+1] = Bins[J];
#local Points[J+1][0] = Points[J][0];
#local Points[J+1][1] = Points[J][1];
#local J = J - 1;
#local Continue = (J >= 0);
#if (Continue)
#local Continue = (Bins[J] > Key);
#end // if
#end // while
#local Bins[J+1] = Key;
#local Points[J+1][0] = TempF_0;
#local Points[J+1][1] = TempF_1;
#end // for
Btw.: I'm suspicious of the *0.999 calculations.
--
Tor Olav
http://subcube.com
https://github.com/t-o-k
Post a reply to this message
|
|