front_n = (x_front - s.X) / v.XripY = s.Y + front_n*v.YripZ = s.Z + front_n*v.Zif (front_n > 0) && (ymin <= ripY && ripY <= ymax) && (zmin <= ripZ && ripZ <= zmax) {...
etc
back_n = (x_back - s.X) / v.XripY = s.Y + back_n*v.YripZ = s.Z + back_n*v.Zif (back_n > 0) && (ymin <= ripY && ripY <= ymax) && (zmin <= ripZ && ripZ <= zmax) {...
etc
Any kind of computational geometry code will have subtle issues in just this area. Broadly, the issue is classification of a point or line as IN, OUT, or ON. Of these, ‘ON’ is the difficult one because floating point prevents perfect calculation where real numbers would allow it. This is because floating point is actually integer math with a companion power function, and the integer math part has the problem in cases of division where the numerators and denominators are relatively prime. This leads to differences in edge and point positions and frustrates the ON calculation, and this the in and out calculation near the edge.
I suggest that you think of this carefully because there is generally no good solution to be found by considering only floating point precision—the same problem will exist at any non-infinite precision.
However, to answer your specific question, yes you can easily truncate float32 to a lower precision. Just force the bits you want to truncate to zero.
Hp is high precision
Lp is low precision
Lp := (unsafe interpret as float)(Mask & (unsafe interpret as integer(Hp))
Mask would be used to discard the lower bits of the word and thus precision.
Mask := ^uint32(0) << k //discard lowest k bits
Nice examples of what this accomplishes are here:
http://www.h-schmidt.net/FloatConverter/IEEE754.html
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
if s.X < xmin || s.Y < ymin || s.Z < zmin || s.X > xmax || s.Y > ymax || s.Z > zmax { //origin is outside box *but* ray intersected with back plane // so ray should have intersected with front plane // probable rounding error at edge/corner intersection return true, true, back_n, back_n, back_p, back_p }
if (multiplied_x < undivided_boundary_value) ==(divisor>0)
if (x < boundary_value)
Sure, as you say for your use case it might be best for you, and you might need different information from the test anyway. Usually in a fast ray tracer you'd pre-calculate the inverse of the direction components and store them (since you do LOTS of ray-bbox intersections for each ray while traversing the bounding hierarchies) then the slab test is pure multiplication and adds. The branchless version then replaces all branch tests with min/max operations. I'd be interested if your div free version is faster and doesn't need the precalculation/storage costs.
Cheers,
Jamie
front_n = (x_front - s.X) / v.XripY = s.Y + front_n*v.YripZ = s.Z + front_n*v.Z
if (front_n > 0) && (ymin <= ripY && ripY <= ymax) && (zmin <= ripZ && ripZ <= zmax) { ..etc ..
front_n_d = (x_front - s.X) // non-divided versionpositive = (v.X > 0)
if (front_n_d > ) == positive &&((ymin-s.Y)*v.X <= front_n_d*v.Y)==positive &&(front_n_d*v.Y <= (ymax-s.Y)*v.X)==positive &&((zmin-s.Z)*v.X <= front_n_d*v.Z)==positive &&(front_n_d*v.Z <= (zmax-s.Z)*v.X))==positive {..etc..
(terms such as ymin-s.Y are reused many times .. I haven't remove them here as it obscures the math.)
front_n = front_n_d / v.X