|
 |
Ref:
http://news.povray.org/povray.general/thread/%3C609d7f7f%241%40news.povray.org%3E/
Web Message: 609a4569$1@news.povray.org
As part of the effort referenced, added a new inbuilt functions called
f_vangle(). A first pass of the help text follows.
---
Returns angle of rotation between two vectors. Function mimics the
traditional VAngle macro shipped with POV-Ray in two ways. The angle is
returned in radians. Wrap with degree() for answer in degrees.
The first an implementation of the acos of the dot product - with -1 to
1 clamping of the dot product - which is the traditional one.
Tor Olav Kristensen suggested a more accurate method to the povray
general news group on May 06, 2021 which is the second method. In
isolation it's obviously slower - sometimes significantly so - (30-40%)
over the traditional acos based method. However, in the blur of branch
predictions supporting both methods and modern CPU speculative execution
the form as implemented herein is often the fastest. When slower it's
not that much slower in the context of typical parser time use.
In targeted random vector experimentation the dot product was found to
return max and min values of +1.00000000000000067 and
-1.00000000000000067, respectively. Meaning with the traditional method
the -1..1 clipping is absolutely necessary to avoid acos domain errors.
Method 0. By targeted random vector experimentation the traditional
method provides for 7 digits of accuracy on when very near a zero angle
or very near pi. In practice, with vectors not near coincident, or near
exactly opposing the accuracy is much better.
Method 1. By targeted random vector experimentation the traditional
method provides for 12 significant digits of accuracy near 0.0 or pi in
angle. It often provides a few more digits.
The largest differences seen between the two methods, over tens of
millions of random vector pairs, was always less than 1e-7.
Using this inbuilt function directly is up to 2.5 times faster no matter
the mode than using the macro VAngle. The macro may be more convenient
in that vectors can be passed directly.
Parameters:
1. First vector x value.
2. First vector y value.
3. First vector z value.
4. Second vector x value.
5. Second vector y value.
6. Second vector z value.
7. Method to use. If 0.0, the traditional acos(dot(v1,v2)) method is
used. If 1.0, Tor Olav's suggested method is used.
---
In math.inc now have:
#macro VAngle(V1, V2) f_vangle(V1.x,V1.y,V1.z,V2.x,V2.y,V2.z,1) #end
#macro VAngleD(V1, V2)
degrees(f_vangle(V1.x,V1.y,V1.z,V2.x,V2.y,V2.z,1))
#end
#macro VRotation(V1, V2, Axis)
(f_vangle(V1.x,V1.y,V1.z,V2.x,V2.y,V2.z,1)
*(vdot(Axis,vcross(V1,V2))<0?-1:1))
#end
#macro VRotationD(V1, V2, Axis)
(degrees(f_vangle(V1.x,V1.y,V1.z,V2.x,V2.y,V2.z,1))
*(vdot(Axis,vcross(V1,V2))<0?-1:1))
#end
Bill P.
Post a reply to this message
|
 |