PDA

View Full Version : Distance = sqrt(abs(x1- x2)^2 + abs(y1- y2)^2 + abs(z1- z2)^2) Producing Garbage.


Dygear
3rd November 2010, 17:32
Why does this code produce these numbers. I'm sure that 0^2 is zero and yet I'm getting an positive float from sqrt(0^2 + 0^2 + 0^2) the statement. The four screen shots below show the car stationary before the start light (http://www.lfsforum.net/attachment.php?attachmentid=109912&stc=1&d=1288811865), stationary 30 seconds after the start light (http://www.lfsforum.net/attachment.php?attachmentid=109913&stc=1&d=1288811865), one minute past the start light (http://www.lfsforum.net/attachment.php?attachmentid=109914&stc=1&d=1288811865) and then at 200.3 mph (http://www.lfsforum.net/attachment.php?attachmentid=109915&stc=1&d=1288811865). Values shown on screen are, from left to right, Green number = X delta, Yellow number = Y delta, Red number = Z delta, White number = distance delta (as compared from last MCI packet, as shown in the code the matters part.) and Blue number = total distance.

Code that matters:
// Calculate Distance
$X = abs($cCoords->X - $lCoords->X);
$Y = abs($cCoords->Y - $lCoords->Y);
$Z = abs($cCoords->Z - $lCoords->Z);
$this->DISTANCE[$PLID] = sqrt($X^2 + $Y^2 + $Z^2);

My point with this being, that if $X, $Y & $Z = 0 then the result of sqrt($X^2 + $Y^2 + $Z^2) should also be zero, but it's not. For reasons I don't understand it's 1.4142135623731. It can't be a math rounding error, it makes no sense for this to be a binary to float conversion error because 0 is just zero! In binary a float is 32 zeros in a row, why would this then produce a non-zero number?

Full code:
<?php
class distance extends Plugins {
const NAME = 'Distance Meter';
const AUTHOR = "Mark 'Dygear' Tomlin";
const VERSION = '0.1.0';
const DESCRIPTION = 'Shows a distance meter.';

private $BTNs = array(); # Array of IS_BTN instances.
private $COORDs = array(); # Array of the last known coords for each player.
private $DISTANCE = array(); # Array of total distance traveled by each player.

public function __construct() {
$this->registerPacket('onMCI', ISP_MCI);
}
public function onMCI($Packet) {
foreach ($Packet->Info as $CompCar) {
$PLID = $CompCar->PLID;
// Spawn a new button instance if one is not here.
if (!isset($this->BTNs[$PLID])) {
$BTN = new IS_BTN;

# X Delta
$BTN->ClickID(13)->T(178)->L(26)->W(3)->H(6)->BStyle(ISB_DARK + 4)->Text('V')->Send();
$BTN->ClickID(23)->T(178)->L(29)->W(19)->H(6)->BStyle(ISB_DARK + 4)->Text('X Delta')->Send();
$BTN->ClickID(33)->T(178)->L(48)->W(3)->H(6)->BStyle(ISB_DARK + 4)->Text('V')->Send();
$this->BTNs[$PLID]['X'] = new IS_BTN;
$this->BTNs[$PLID]['X']->ClickID(3)->T(184)->L(26)->W(25)->H(6)->BStyle(ISB_DARK + 4)->Send()->W(0)->H(0);

# Y Delta
$BTN->ClickID(14)->T(178)->L(51)->W(3)->H(6)->BStyle(ISB_DARK + 1)->Text('V')->Send();
$BTN->ClickID(24)->T(178)->L(54)->W(19)->H(6)->BStyle(ISB_DARK + 1)->Text('Y Delta')->Send();
$BTN->ClickID(34)->T(178)->L(73)->W(3)->H(6)->BStyle(ISB_DARK + 1)->Text('V')->Send();
$this->BTNs[$PLID]['Y'] = new IS_BTN;
$this->BTNs[$PLID]['Y']->ClickID(4)->T(184)->L(51)->W(25)->H(6)->BStyle(ISB_DARK + 1)->Send()->W(0)->H(0);

# Z Delta
$BTN->ClickID(15)->T(178)->L(76)->W(3)->H(6)->BStyle(ISB_DARK + 5)->Text('V')->Send();
$BTN->ClickID(25)->T(178)->L(79)->W(19)->H(6)->BStyle(ISB_DARK + 5)->Text('Z Delta')->Send();
$BTN->ClickID(35)->T(178)->L(98)->W(3)->H(6)->BStyle(ISB_DARK + 5)->Text('V')->Send();
$this->BTNs[$PLID]['Z'] = new IS_BTN;
$this->BTNs[$PLID]['Z']->ClickID(5)->T(184)->L(76)->W(25)->H(6)->BStyle(ISB_DARK + 5)->Send()->W(0)->H(0);

# Distance Delta
$BTN->ClickID(16)->T(178)->L(101)->W(3)->H(6)->BStyle(ISB_DARK + 3)->Text('V')->Send();
$BTN->ClickID(26)->T(178)->L(104)->W(19)->H(6)->BStyle(ISB_DARK + 3)->Text('Distance Delta')->Send();
$BTN->ClickID(36)->T(178)->L(123)->W(3)->H(6)->BStyle(ISB_DARK + 3)->Text('V')->Send();
$this->BTNs[$PLID]['Dist'] = new IS_BTN;
$this->BTNs[$PLID]['Dist']->ClickID(6)->T(184)->L(101)->W(25)->H(6)->BStyle(ISB_DARK + ISB_RIGHT + 3)->Send()->W(0)->H(0);

# Total Distance
$BTN->ClickID(17)->T(178)->L(126)->W(3)->H(6)->BStyle(ISB_DARK + 6)->Text('V')->Send();
$BTN->ClickID(27)->T(178)->L(129)->W(19)->H(6)->BStyle(ISB_DARK + 6)->Text('Total Distance')->Send();
$BTN->ClickID(37)->T(178)->L(148)->W(3)->H(6)->BStyle(ISB_DARK + 6)->Text('V')->Send();
$this->BTNs[$PLID]['Totl'] = new IS_BTN;
$this->BTNs[$PLID]['Totl']->ClickID(7)->T(184)->L(126)->W(25)->H(6)->BStyle(ISB_DARK + ISB_RIGHT + 6)->Send()->W(0)->H(0);
}

// Setup our Coord data.
$lCoords = (isset($this->COORDs[$PLID])) ? $this->COORDs[$PLID] : $CompCar;
$cCoords = $CompCar;

// Calculate Distance
$X = abs($cCoords->X - $lCoords->X);
$Y = abs($cCoords->Y - $lCoords->Y);
$Z = abs($cCoords->Z - $lCoords->Z);
$this->DISTANCE[$PLID] = sqrt($X^2 + $Y^2 + $Z^2);

// Update Buttons
$this->BTNs[$PLID]['X']->Text($X)->Send();
$this->BTNs[$PLID]['Y']->Text($Y)->Send();
$this->BTNs[$PLID]['Z']->Text($Z)->Send();
$this->BTNs[$PLID]['Dist']->Text($this->DISTANCE[$PLID])->Send();
$this->BTNs[$PLID]['Totl']->Text($this->BTNs[$PLID]['Totl']->Text += $this->DISTANCE[$PLID])->Send();
$this->COORDs[$PLID] = $cCoords;
}
}
}
?>

cargame.nl
3rd November 2010, 18:24
I don't see the screen shots?

You forgot to attach.

Dygear
3rd November 2010, 18:26
I don't see the screen shots?

You forgot to attach.

You just happened to reply as I was removing the old code and screen shots and was updating it with the new code and screen shots. (The new screen shots show more detail on screen so you don't have to refer to the key I posted at the top of my post.)

Dygear
3rd November 2010, 19:51
Fixed by changing from the ^2 syntax to the pow() (http://php.net/manual/en/function.pow.php) function.

// Calculate Distance
$X = abs($cCoords->X - $lCoords->X);
$Y = abs($cCoords->Y - $lCoords->Y);
$Z = abs($cCoords->Z - $lCoords->Z);
$this->DISTANCE[$PLID] = sqrt(pow($X, 2) + pow($Y, 2) + pow($Z, 2));

herki
5th November 2010, 09:57
Fixed by changing from the ^2 syntax to the pow() (http://php.net/manual/en/function.pow.php) function.

// Calculate Distance
$X = abs($cCoords->X - $lCoords->X);
$Y = abs($cCoords->Y - $lCoords->Y);
$Z = abs($cCoords->Z - $lCoords->Z);
$this->DISTANCE[$PLID] = sqrt(pow($X, 2) + pow($Y, 2) + pow($Z, 2));
Ah, classic mistake. Happens to me once in a while too, ^ often being the bitwise XOR operator.

morpha
5th November 2010, 10:08
Obviously in this particular case, this would be more efficient: // Calculate Distance
$X = abs($cCoords->X - $lCoords->X);
$Y = abs($cCoords->Y - $lCoords->Y);
$Z = abs($cCoords->Z - $lCoords->Z);
$this->DISTANCE[$PLID] = sqrt(($X * $X) + ($Y * $Y) + ($Z * $Z));

herki
6th November 2010, 10:04
Because it uses like one elementary operation less? PHP itself is slow enough that that won't make a difference.

morpha
6th November 2010, 13:01
Because it uses like one elementary operation less? PHP itself is slow enough that that won't make a difference.

Believe me, if it's performed for every car on the track at a frequency of 20Hz, it does. Especially if you're hosting on an ancient Celeron 2.0.

Dygear
6th November 2010, 16:42
Ah, classic mistake. Happens to me once in a while too, ^ often being the bitwise XOR operator.

Yeah, I felt like a fool after I realized my mistake. It was pretty rookie of me to do.

Because it uses like one elementary operation less? PHP itself is slow enough that that won't make a difference.
Believe me, if it's performed for every car on the track at a frequency of 20Hz, it does. Especially if you're hosting on an ancient Celeron 2.0.

It is surprisingly important that MCI packets get parsed as fast as they can. Because it can be 20Hz * Number of servers.