the .getDistanceTo() function gives you very nice values on distances, but do we need all those digits?
I wrote a couple of functions that doesn’t calculate more digits than necessary, you just choose a margin of error. First I just have to say this:
I have not benchmarked these functions against getDistanceTo(), so I don’t know if they actually are faster. Python is supposed to be slower than C++ so maybe my effort was in vain. I’ll try to make a test scene some time.
The main thing here is to avoid computing roots, these are time consuming.
Distance is normally calculated: sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2) where x1,y1,z1 are the first positions coordinates and x2,y2,z2 is the second’s. Sqrt is the square root, which we will try to avoid or simplify.
- If you want to compare two distances. If you just want to know which of two or more objects is closer to a place or object. Just compare the squares (^2 or **2) of the distances, skip the Sqrt. If a square is bigger than another the root of that square will also be bigger than the other’s root.
This function will give you the square of the distance between two objects.
def squareDist(ob1,ob2): d = (ob1.position-ob2.position)**2+(ob1.position-ob2.position)**2+(ob1.position-ob2.position)**2 return(d)
- If you want an approximate distance. Say you want to know how far away something is but it doesn’t have to be exact. We use the Babylonian method to compute the square root but stop when we have reached the desired precision. If you are interested http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
This is pretty much just that algorithm, except I skipped the case S > 1, it still finds the value just that the starting estimate is a bit more off.
def oddEven(number): if number%2==0: return(6) else: return(2) def approxDist(ob1,ob2,e): S = (ob1.position-ob2.position)**2+(ob1.position-ob2.position)**2+(ob1.position-ob2.position)**2 n = len(str(int(S))) D, n = oddEven(n) x = D * 10**n x2 = (x+S/x)/2 while x-x2 > e: x = x2 x2 = (x+S/x)/2 return(x2)
This function calculates the distance between two objects, ob1 and ob2 with the maximum error below e. It often gets a lot more precise than e. If you for example want to know the difference between your object cube and sphere and need no decimal digits it would be
distance = approxDist(cube,sphere,1)
So the error has to be smaller than 1.
If the objects had the coordinates [1,5,7] and [2,2,2] you would get the number 5.91666666667 when the exact number is 5.9160797831.
distance = approxDist(cube,sphere,0.1)
would give the same result here because the error is still smaller than 0.1
distance = approxDist(cube,sphere,0.01)
would give 5.91607981221.
if e = 0 then it finds the exact square root.
- If you want the square root of a value. Maybe you want to calculate the square root of a value for some reason, the same algorithm but on just one number instead of two objects:
def oddEven(n): if n%2==0: n -= 2 n /= 2 return(6,n) else: n -= 1 n /= 2 return(2,n) def approxRoot(S,e): n = len(str(int(S))) D,n = oddEven(n) x = D * 10**n x2 = (x+S/x)/2 while x-x2 > e: x = x2 x2 = (x+S/x)/2 return(x2)
where S is a float and the maximum error is lesser than e. So
would give 1.41666666667 when a more exact value is 1.41421356237. Remember to use floats! otherwise it won’t work. If you give it 2 instead of 2.0 you will end up with 1 instead of 1.41666666667