Before tackling this one, take a look at
this one.
+D
/ /
/  / 
/  / 
/  / 
C+ 
   
 B+
 /  /
 /  /
 /  /
/ /
+A
A, B, C and D are nonadjacent vertices of a cube. There is a point P in space such that PA=3, PB=5, PC=7, and PD=6. Find the distance from P to the other four vertices and find the length of the edge of the cube.
There are two answers, one with P outside the cube and one with P inside the cube.
(In reply to
PD can't be 9. Correct Restrictions on PD. by np_rt)
Fortunately I chose my coordinate system the same as np_rt. My program chooses random values, within reason, for x, y, z and the size of the cube. It starts with a certain increment and figures the total discrepancies from the distances given. It does this for all possible locations with x, y, z and size incremented or decremented by the increment (delta), or not incremented  but at least one must be incremented or decremented. Whichever produces the best result is taken as the new starting point. I tried various automatic schemes for decreasing the increment for finer results, but eventually had to make this a human intervention.
The program, using 8 as the goal for PD is:
DEFDBL AZ
size = 6
x = 5
y = 3
z = 1
aGoal = 3: bGoal = 5: cGoal = 7: dGoal = 8
DO
x = RND(1) * 11
y = RND(1) * 4
z = RND(1) * 4
size = RND(1) * 4
delta = .1
CLS
GOSUB evalPos
aOff = da  3
bOff = db  5
cOff = dc  7
dOff = dd  11
DO
FOR itr = 1 TO 48
leastTot = 9999
FOR dx = delta TO delta STEP delta
xTr = x + dx
FOR dy = delta TO delta STEP delta
yTr = y + dy
FOR dz = delta TO delta STEP delta
zTr = z + dz
FOR dS = delta TO delta STEP delta
sizeTr = size + dS
IF dx <> 0 OR dy <> 0 OR dz <> 0 OR dS <> 0 THEN
GOSUB evalTrPos
IF totTr < leastTot THEN
dxP = dx: dyP = dy: dzP = dz: dSP = dS
leastTot = totTr
END IF
END IF
NEXT dS
NEXT dz
NEXT dy
NEXT dx
xTr = x + 2 * dxP: yTr = y + 2 * dyP: zTr = z + 2 * dzP
sizeTr = size + 2 * dSP
GOSUB evalTrPos
'IF totTr > leastTot THEN delta = delta * .8
x = x + dxP: y = y + dyP: z = z + dzP: size = size + dSP
GOSUB evalPos
PRINT USING "#.### #.### #.###; ##.#### ##.#### ##.#### ##.#### ##.####"; x; y; z; size; da; db; dc; dd
NEXT itr
DO: a$ = INKEY$: LOOP UNTIL a$ > ""
IF a$ = "" THEN delta = delta / 2
LOOP UNTIL a$ = CHR$(27)
LOOP
END
evalTrPos:
daTr = SQR((xTr  sizeTr) ^ 2 + (yTr  sizeTr) ^ 2 + zTr ^ 2)
dbTr = SQR(xTr ^ 2 + yTr ^ 2 + zTr ^ 2)
dcTr = SQR((xTr  sizeTr) ^ 2 + (zTr  sizeTr) ^ 2 + yTr ^ 2)
ddTr = SQR((yTr  sizeTr) ^ 2 + (zTr  sizeTr) ^ 2 + xTr ^ 2)
totTr = ABS(daTr  aGoal) + ABS(dbTr  bGoal) + ABS(dcTr  cGoal) + ABS(ddTr  dGoal)
RETURN
evalPos:
da = SQR((x  size) ^ 2 + (y  size) ^ 2 + z ^ 2)
db = SQR(x ^ 2 + y ^ 2 + z ^ 2)
dc = SQR((x  size) ^ 2 + (z  size) ^ 2 + y ^ 2)
dd = SQR((y  size) ^ 2 + (z  size) ^ 2 + x ^ 2)
totTr = ABS(da  aGoal) + ABS(db  bGoal) + ABS(dc  cGoal) + ABS(dd  dGoal)
RETURN
After a few iterations we get the following line:
4.043 2.530 1.502; 4.9600 3.0000 5.0000 7.0000 8.0000
Indicating the cube side is 4.9600 with x=4.043, y=2.530, z=1.502. The negative z indicates the point is external to the cube, below the bottom as shown.
I never seem to get a point within the cube.

Posted by Charlie
on 20040718 19:58:24 