I edited my code, see below:
I am trying to do an array with the time enroute. $distance works properly.
Now "ete" is giving this result for each leg: NaN Hrs. NaN Mins.
I replaced distance with 1500 and it spit out a result. That leads me to believe this [new Array();] is the problem.
I did some more digging
var distance = new Array(""); is giving me this result: 431,910,746,923
Does that mean the implode did not work?
<script type="text/javascript">
var distance = new Array(<?=implode(', ', $distance)?>);
function Aircraft() {
var mylist = document.getElementById("myList");
for(var i = 0; i < distance.length; i++) {
var hour = (Math.floor(1500 / mylist.options[mylist.selectedIndex].value));
var minute = Math.round((Math.round(1500 / mylist.options[mylist.selectedIndex].value) - hour) * 60);
document.getElementById("ete" + i).innerHTML = hour + " Hrs. " + minute + " Mins.";
}
}
</script>
We're getting closer I think...
$distance = array();
for($i = 0, $size = sizeof($Row1); $i < ($size - 1); ++$i){
$distance[$i] = ROUND((ACOS(SIN($Row2[$i][4] * PI() / 180) * SIN($Row1[$i][4] * PI() / 180) + COS($Row2[$i][4] * PI() / 180) * COS($Row1[$i][4] * PI() / 180) * COS(($Row2[$i][5] - $Row1[$i][5]) * PI() / 180)) * 180 / PI()) * 60 );
echo "<td width=100>" . $distance[$i] . " NM</td>";
echo "<td width=100><span id=\"ete" . $i . "\"></span></td>";
}
?>
<script type="text/javascript">
var distance = new Array(<?=implode(', ', $distance)?>);
function Aircraft() {
var mylist = document.getElementById("myList");
for(var i = 0; i < distance.length; i++) {
var hour = (Math.floor(distance / mylist.options[mylist.selectedIndex].value));
var minute = Math.round((Math.round(distance / mylist.options[mylist.selectedIndex].value) - hour) * 60);
document.getElementById("ete" + i).innerHTML = hour + " Hrs. " + minute + " Mins.";
}
}
Here is where Aircraft() is used:
<select id=\"myList\" style=\"width:150px;\" onchange=\"Aircraft()\">
<option>Select Aircraft</option>
<option value=\"300\">King Air 350</option>
<option value=\"450\">G-V</option>
<option value=\"470\">GLEX</option>
<option value=\"350\">Astra</option>
</select>
Not an answer to your direct question, but you don't need to write code like this in PHP:
for($i = 0, $size = sizeof($Row1); $i < $size; ++$i){
if ($i < ($size-1)){
$Row1[$i]['a']...
$Row2[$i]['b']...
}
}
You can use foreach() to iterate over an array:
foreach ($Row1 as $k => $r1){
$r2 = $Row2[$k];
$r1['a']...
$r2['a']...
}
That aside, your code does not do what you want for a couple of reasons. Assuming that the loop actually runs more than once, you're creating multiple functions all called Aircraft() - function names must be unique. Assuming you are actually running the function, then it will only run the most recently defined version of the function (i.e. the last one). You probably want something like this:
<table>
<?
# output table cells we will populate
foreach (....){
echo "<tr>";
echo "<td id=\"$id\"></td>";
echo "</tr>";
}
?>
</table>
<script>
function Aircraft(distance, id){
body of javascript here,
inserts results into element with ID of `id`
}
<?
# now output calls to the JS function that will produce the output
foreach (....){
$distance = ...;
echo "Aircraft($distance, $id);\n";
}
?>
</script>
Solved it:
<script type="text/javascript">
var distance = new Array("<?php echo implode('","',$distance)?>");
function Aircraft() {
var mylist = document.getElementById("myList");
for(var i = 0; i < distance.length; i++) {
var hour = (Math.floor(distance[i] / mylist.options[mylist.selectedIndex].value));
var minute = Math.round(((distance[i] / mylist.options[mylist.selectedIndex].value) - hour) * 60);
document.getElementById("ete" + i).innerHTML = hour + " Hrs. " + minute + " Mins.";
}
}
</script>
If I understand correctly, you want to calculate several time estimates for different distances according to the selected aircraft.
To accomplish this, a JavaScript array with the distances could be stored. Then, the Aircraft() function would only need to iterate through the different spans filling in the new ETA's.
Try replacing the first block of code with this:
<?php
$distance = array();
for ($i = 0, $size = sizeof($Row1); $i < ($size - 1); ++$i) {
$distance[$i] = ROUND((ACOS(SIN($Row2[$i][4] * PI() / 180) * SIN($Row1[$i][4] * PI() / 180) + COS($Row2[$i][4] * PI() / 180) * COS($Row1[$i][4] * PI() / 180) * COS(($Row2[$i][5] - $Row1[$i][5]) * PI() / 180)) * 180 / PI()) * 60 );
echo "<td width=100>" . $distance[$i] . " NM</td>";
echo "<td width=100><span id=\"ete" . $i . "\"></span></td>";
}
?>
<script type="text/javascript">
var distances = new Array("<?=implode('", "', $distance)?>");
function Aircraft() {
var mylist = document.getElementById("myList");
for(var i = 0; i < distances.length; i++) {
var hour = (Math.floor(distance / mylist.options[mylist.selectedIndex].value));
var minute = Math.round((Math.round(distance / mylist.options[mylist.selectedIndex].value) - hour) * 60);
document.getElementById("ete" + i).innerHTML = hour + " Hrs. " + minute + " Mins.";
}
}
</script>
Related
So i want to load a gpx file and get all the cordinates and calculate the total distance traveled, but im stuck with this code:
<?php
$xml = simplexml_load_file("data/example.gpx");
echo $xml->metadata->author->name;
echo "</br>";
echo "</br>";
echo "</br>";
$lon1=0;
$lat1=0;
$lon2=0;
$lat2=0;
$alt1=0;
$alt2=0;
$dist=0;
$brr = count($xml->trk->trkseg);
$brf = 0;
for($i = 0; $i<$brr; $i++){
$br = count($xml->trk->trkseg[$i]->trkpt);
$brf= $brf + $br;
for($j = 0; $j<$br;$j++){
$lat2= (float) $xml->trk->trkseg[$i]->trkpt[$j]['lat'];
$lon2= (float) $xml->trk->trkseg[$i]->trkpt[$j]['lon'];
$alt2= (float) $xml->trk->trkseg[$i]->trkpt[$j]->ele;
$lon2 = $alt2 * cos($lat2) * sin($lon2);
$lat2 = $alt2 * sin($lat2);
$alt2 = $alt2 * cos($lat2) * cos($lon2);
if ($j==0){ //this is just for the first time because first points are not set
$lat1=$lat2;
$lon1=$lon2;
$alt1= $alt2;
}
$cdist = sqrt(pow(($lat2-$lat1),2) + pow(($lon2-$lon1),2) + pow(($alt2-$alt1),2));
$dist = $dist + $cdist;
$lat1=$lat2;
$lon1=$lon2;
$alt1=$alt2;
}
}
echo 'Distance = '.$dist;
echo '</br>';
echo 'number of coordinates = '.$brf;
?>
as result for distance i get the number 4592.6244157763 instead of 4.10km (~~4100), but coordinates are good, it goes through all coordinates. (also, the gpx file is from endomondo if it matters)
Fixed the code, in case anyone needs it, here it is:
<?php
$xml = simplexml_load_file("data/vladantd.gpx");
echo $xml->metadata->author->name;
echo "</br>";
echo "</br>";
echo "</br>";
$lon1=0;
$lat1=0;
$lon2=0;
$lat2=0;
$alt1=0;
$alt2=0;
$dist=0;
$brr = count($xml->trk->trkseg);
$brf = 0;
for($i = 0; $i<$brr; $i++){
$br = count($xml->trk->trkseg[$i]->trkpt);
$brf= $brf + $br;
for($j = 0; $j<$br;$j++){
if($j==0)
{
$j=1;
$g=1;
}
$lat2= (float) $xml->trk->trkseg[$i]->trkpt[$j]['lat'];
$lon2= (float) $xml->trk->trkseg[$i]->trkpt[$j]['lon'];
$alt2= (float) $xml->trk->trkseg[$i]->trkpt[$j]->ele;
$lon2 = $alt2 * cos($lat2) * sin($lon2);
$lat2 = $alt2 * sin($lat2);
$alt2 = $alt2 * cos($lat2) * cos($lon2);
if ($g==1){
$lat1=$lat2;
$lon1=$lon2;
$alt1= $alt2;
$j=0;
$g=0;
}
$cdist = sqrt(pow(($lat2-$lat1),2) + pow(($lon2-$lon1),2) + pow(($alt2-$alt1),2));
$dist = $dist + $cdist;
$lat1=$lat2;
$lon1=$lon2;
$alt1=$alt2;
}
}
echo 'Distance = '.$dist;
echo '</br>';
echo 'number of coordinates = '.$brf;
?>
okay, so the files that i use, every first trkpt in every trkseg doesnt have an altitude, so if j==0 then set j to 1, so it skips that first point (it sets points 1 time every few seconds so it shouldnt make a big difference (in my case) and at the same time i've set another variable g to 1, so that we can at the end of this current loop, return j back to 0 so the j++ increases it to 1 instead of skipping the point and increasing it to 2, rest should be clear, if you have any questions, just ask ^^
EDIT:
The code isnt working good. The longer the distance, the bigger the mistake it makes, for 8.1km it shows 9km, tested it out on a few gpx files and noticed. Sorry, if someone has a solution, would mean a lot!
anyone can write a PHP script as this calculator that calculates the percentage of increase and decrease?
http://www.marshu.com/articles/calculate-percentage-increase-decrease-percent-calculator.php
Thank you.
If you open the source of that page, you will find following:
function PercentIncrease(form) {
var num1 = form.num1.value;
var num2 = form.num2.value;
return ((num2 - num1) / num1 * 100 + "%");
}
Let us know if you have problems with PHP syntax.
Update: Obviously you have, so:
function PercentIncrease($num1, $num2) {
return (($num2 - $num1) / $num1 * 100 . "%");
}
$n1 = 10;
$n2 = 200;
echo PercentIncrease($n1, $n2); //output 1900%
echo PercentIncrease($n2, $n1); //output -95%
You could make a function like :
function calcPercentInc($a, $b)
{
return (100 * (($a / $b) - 1)) . '%';
}
I have a code not very professional but it does what i want :). The code is basically doing if shop open count for how long if closed count how long left form opening. Now i wanted to style it with jQuery Countdown but i cant find any to just count hours,minutes, maybe seconds. I was trying UNIX countdowns but dunno what i`m doing wrong. I would like to ask you fellow citizens of Stackoverflow to help me out with this.
This is my code ( Just don`t be haters :) )
date_default_timezone_set('Greenwich'); //Fixes my server location
$openingtime = strtotime('06:00'); //Opening time
$closingtime = strtotime('23:10'); //Closing time
$timenow = strtotime('now'); //Current Server Time
$twentyfourhours = "24:00"; //Hours in a day
//echo date('G:i', $openingtime); //Just texting
//echo date('G:i', $closingtime);
//echo date('H:i', $timenow);
//echo $twentyfourhours;// Testing ends here
$openingin = $twentyfourhours - $timenow + $openingtime; //24:00 - 23:20 + 6:00 = How long left for opening
$closingdown = $closingtime - $timenow; //23:10 - 23:20 How long left to close
//If current time value is bigger then closing time then display when the shop will re-open again
if (date('H:i', $timenow) > date('H:i', $closingtime))
{
echo "The shop will be open in ".date('H:i', $openingin)." hours";
}
//If current time value is lower then closing time then display how long the shop will stay open
elseif (date('H:i', $timenow) < date('H:i', $closingtime))
{
echo "The shop will be open for ".date('H:i', $closingdown)." hours";
}
Ok i have managed to found one but now if you will go to My Testing Ground You will notice that the seconds instead of starting countdown from 60 they start from 00,99,98,97,97 and all the way down :( dunno why its happening im attaching JS code
var flipCounter = function(d, options){
// Default values
var defaults = {
value: 0,
inc: 1,
pace: 1000,
auto: true,
tFH: 39,
bFH: 64,
fW: 53,
bOffset: 390
};
var o = options || {},
doc = window.document,
divId = typeof d !== 'undefined' && d !== '' ? d : 'flip-counter',
div = doc.getElementById(divId);
for (var opt in defaults) o[opt] = (opt in o) ? o[opt] : defaults[opt];
var digitsOld = [], digitsNew = [], subStart, subEnd, x, y, nextCount = null, newDigit, newComma,
best = {
q: null,
pace: 0,
inc: 0
};
/**
* Sets the value of the counter and animates the digits to new value.
*
* Example: myCounter.setValue(500); would set the value of the counter to 500,
* no matter what value it was previously.
*
* #param {int} n
* New counter value
*/
this.setValue = function(n){
if (isNumber(n)){
x = o.value;
y = n;
o.value = n;
digitCheck(x,y);
}
return this;
};
/**
* Sets the increment for the counter. Does NOT animate digits.
*/
this.setIncrement = function(n){
o.inc = isNumber(n) ? n : defaults.inc;
return this;
};
/**
* Sets the pace of the counter. Only affects counter when auto == true.
*
* #param {int} n
* New pace for counter in milliseconds
*/
this.setPace = function(n){
o.pace = isNumber(n) ? n : defaults.pace;
return this;
};
/**
* Sets counter to auto-incrememnt (true) or not (false).
*
* #param {bool} a
* Should counter auto-increment, true or false
*/
this.setAuto = function(a){
if (a && ! o.atuo){
o.auto = true;
doCount();
}
if (! a && o.auto){
if (nextCount) clearNext();
o.auto = false;
}
return this;
};
/**
* Increments counter by one animation based on set 'inc' value.
*/
this.step = function(){
if (! o.auto) doCount();
return this;
};
/**
* Adds a number to the counter value, not affecting the 'inc' or 'pace' of the counter.
*
* #param {int} n
* Number to add to counter value
*/
this.add = function(n){
if (isNumber(n)){
x = o.value;
o.value += n;
y = o.value;
digitCheck(x,y);
}
return this;
};
/**
* Subtracts a number from the counter value, not affecting the 'inc' or 'pace' of the counter.
*
* #param {int} n
* Number to subtract from counter value
*/
this.subtract = function(n){
if (isNumber(n)){
x = o.value;
o.value -= n;
if (o.value >= 0){
y = o.value;
}
else{
y = "0";
o.value = 0;
}
digitCheck(x,y);
}
return this;
};
/**
* Increments counter to given value, animating by current pace and increment.
*
* #param {int} n
* Number to increment to
* #param {int} t (optional)
* Time duration in seconds - makes increment a 'smart' increment
* #param {int} p (optional)
* Desired pace for counter if 'smart' increment
*/
this.incrementTo = function(n, t, p){
if (nextCount) clearNext();
// Smart increment
if (typeof t != 'undefined'){
var time = isNumber(t) ? t * 1000 : 10000,
pace = typeof p != 'undefined' && isNumber(p) ? p : o.pace,
diff = typeof n != 'undefined' && isNumber(n) ? n - o.value : 0,
cycles, inc, check, i = 0;
best.q = null;
// Initial best guess
pace = (time / diff > pace) ? Math.round((time / diff) / 10) * 10 : pace;
cycles = Math.floor(time / pace);
inc = Math.floor(diff / cycles);
check = checkSmartValues(diff, cycles, inc, pace, time);
if (diff > 0){
while (check.result === false && i < 100){
pace += 10;
cycles = Math.floor(time / pace);
inc = Math.floor(diff / cycles);
check = checkSmartValues(diff, cycles, inc, pace, time);
i++;
}
if (i == 100){
// Could not find optimal settings, use best found so far
o.inc = best.inc;
o.pace = best.pace;
}
else{
// Optimal settings found, use those
o.inc = inc;
o.pace = pace;
}
doIncrement(n, true, cycles);
}
}
// Regular increment
else{
doIncrement(n);
}
}
/**
* Gets current value of counter.
*/
this.getValue = function(){
return o.value;
}
/**
* Stops all running increments.
*/
this.stop = function(){
if (nextCount) clearNext();
return this;
}
//---------------------------------------------------------------------------//
function doCount(){
x = o.value;
o.value += o.inc;
y = o.value;
digitCheck(x,y);
if (o.auto === true) nextCount = setTimeout(doCount, o.pace);
}
function doIncrement(n, s, c){
var val = o.value,
smart = (typeof s == 'undefined') ? false : s,
cycles = (typeof c == 'undefined') ? 1 : c;
if (smart === true) cycles--;
if (val != n){
x = o.value,
o.auto = true;
if (val + o.inc <= n && cycles != 0) val += o.inc
else val = n;
o.value = val;
y = o.value;
digitCheck(x,y);
nextCount = setTimeout(function(){doIncrement(n, smart, cycles)}, o.pace);
}
else o.auto = false;
}
function digitCheck(x,y){
digitsOld = splitToArray(x);
digitsNew = splitToArray(y);
var diff,
xlen = digitsOld.length,
ylen = digitsNew.length;
if (ylen > xlen){
diff = ylen - xlen;
while (diff > 0){
addDigit(ylen - diff + 1, digitsNew[ylen - diff]);
diff--;
}
}
if (ylen < xlen){
diff = xlen - ylen;
while (diff > 0){
removeDigit(xlen - diff);
diff--;
}
}
for (var i = 0; i < xlen; i++){
if (digitsNew[i] != digitsOld[i]){
animateDigit(i, digitsOld[i], digitsNew[i]);
}
}
}
function animateDigit(n, oldDigit, newDigit){
var speed, step = 0, w, a,
bp = [
'-' + o.fW + 'px -' + (oldDigit * o.tFH) + 'px',
(o.fW * -2) + 'px -' + (oldDigit * o.tFH) + 'px',
'0 -' + (newDigit * o.tFH) + 'px',
'-' + o.fW + 'px -' + (oldDigit * o.bFH + o.bOffset) + 'px',
(o.fW * -2) + 'px -' + (newDigit * o.bFH + o.bOffset) + 'px',
(o.fW * -3) + 'px -' + (newDigit * o.bFH + o.bOffset) + 'px',
'0 -' + (newDigit * o.bFH + o.bOffset) + 'px'
];
if (o.auto === true && o.pace <= 300){
switch (n){
case 0:
speed = o.pace/6;
break;
case 1:
speed = o.pace/5;
break;
case 2:
speed = o.pace/4;
break;
case 3:
speed = o.pace/3;
break;
default:
speed = o.pace/1.5;
break;
}
}
else{
speed = 80;
}
// Cap on slowest animation can go
speed = (speed > 80) ? 80 : speed;
function animate(){
if (step < 7){
w = step < 3 ? 't' : 'b';
a = doc.getElementById(divId + "_" + w + "_d" + n);
if (a) a.style.backgroundPosition = bp[step];
step++;
if (step != 3) setTimeout(animate, speed);
else animate();
}
}
animate();
}
// Creates array of digits for easier manipulation
function splitToArray(input){
return input.toString().split("").reverse();
}
// Adds new digit
function addDigit(len, digit){
var li = Number(len) - 1;
newDigit = doc.createElement("ul");
newDigit.className = 'cd';
newDigit.id = divId + '_d' + li;
newDigit.innerHTML = '<li class="t" id="' + divId + '_t_d' + li + '"></li><li class="b" id="' + divId + '_b_d' + li + '"></li>';
if (li % 2 == 0){
newComma = doc.createElement("ul");
newComma.className = 'cd';
newComma.innerHTML = '<li class="s"></li>';
div.insertBefore(newComma, div.firstChild);
}
div.insertBefore(newDigit, div.firstChild);
doc.getElementById(divId + "_t_d" + li).style.backgroundPosition = '0 -' + (digit * o.tFH) + 'px';
doc.getElementById(divId + "_b_d" + li).style.backgroundPosition = '0 -' + (digit * o.bFH + o.bOffset) + 'px';
}
// Removes digit
function removeDigit(id){
var remove = doc.getElementById(divId + "_d" + id);
div.removeChild(remove);
// Check for leading comma
var first = div.firstChild.firstChild;
if ((" " + first.className + " ").indexOf(" s ") > -1 ){
remove = first.parentNode;
div.removeChild(remove);
}
}
// Sets the correct digits on load
function initialDigitCheck(init){
// Creates the right number of digits
var initial = init.toString(),
count = initial.length,
bit = 1, i;
for (i = 0; i < count; i++){
newDigit = doc.createElement("ul");
newDigit.className = 'cd';
newDigit.id = divId + '_d' + i;
newDigit.innerHTML = newDigit.innerHTML = '<li class="t" id="' + divId + '_t_d' + i + '"></li><li class="b" id="' + divId + '_b_d' + i + '"></li>';
div.insertBefore(newDigit, div.firstChild);
if (bit != (count) && bit % 2 == 0){
newComma = doc.createElement("ul");
newComma.className = 'cd';
newComma.innerHTML = '<li class="s"></li>';
div.insertBefore(newComma, div.firstChild);
}
bit++;
}
// Sets them to the right number
var digits = splitToArray(initial);
for (i = 0; i < count; i++){
doc.getElementById(divId + "_t_d" + i).style.backgroundPosition = '0 -' + (digits[i] * o.tFH) + 'px';
doc.getElementById(divId + "_b_d" + i).style.backgroundPosition = '0 -' + (digits[i] * o.bFH + o.bOffset) + 'px';
}
// Do first animation
if (o.auto === true) nextCount = setTimeout(doCount, o.pace);
}
// Checks values for smart increment and creates debug text
function checkSmartValues(diff, cycles, inc, pace, time){
var r = {result: true}, q;
// Test conditions, all must pass to continue:
// 1: Unrounded inc value needs to be at least 1
r.cond1 = (diff / cycles >= 1) ? true : false;
// 2: Don't want to overshoot the target number
r.cond2 = (cycles * inc <= diff) ? true : false;
// 3: Want to be within 10 of the target number
r.cond3 = (Math.abs(cycles * inc - diff) <= 10) ? true : false;
// 4: Total time should be within 100ms of target time.
r.cond4 = (Math.abs(cycles * pace - time) <= 100) ? true : false;
// 5: Calculated time should not be over target time
r.cond5 = (cycles * pace <= time) ? true : false;
// Keep track of 'good enough' values in case can't find best one within 100 loops
if (r.cond1 && r.cond2 && r.cond4 && r.cond5){
q = Math.abs(diff - (cycles * inc)) + Math.abs(cycles * pace - time);
if (best.q === null) best.q = q;
if (q <= best.q){
best.pace = pace;
best.inc = inc;
}
}
for (var i = 1; i <= 5; i++){
if (r['cond' + i] === false){
r.result = false;
}
}
return r;
}
// http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric/1830844
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function clearNext(){
clearTimeout(nextCount);
nextCount = null;
}
// Start it up
initialDigitCheck(o.value);
};`
I have a problem with my file. I'm making Travian Clone script and we went really far. Now we decided to add artefacts into game.
Goal is to show closest artefacts to the current village we are in. The code is:
function getDistance($coorx1, $coory1, $coorx2, $coory2) {
$max = 2 * WORLD_MAX + 1;
$x1 = intval($coorx1);
$y1 = intval($coory1);
$x2 = intval($coorx2);
$y2 = intval($coory2);
$distanceX = min(abs($x2 - $x1), $max - abs($x2 - $x1));
$distanceY = min(abs($y2 - $y1), $max - abs($y2 - $y1));
$dist = sqrt(pow($distanceX, 2) + pow($distanceY, 2));
return round($dist, 1);
}
unset($reqlvl);
unset($effect);
$arts = mysql_query("SELECT * FROM ".TB_PREFIX."artefacts WHERE id > 0");
$rows = array();
while($row = mysql_fetch_array($arts)) {
$query = mysql_query('SELECT * FROM `' . TB_PREFIX . 'wdata` WHERE `id` = ' . $row['vref']);
$coor2 = mysql_fetch_assoc($query);
$wref = $village->wid;
$coor = $database->getCoor($wref);
$dist = getDistance($coor['x'], $coor['y'], $coor2['x'], $coor2['y']);
$rows[$dist] = $row;
}
ksort($rows, SORT_ASC);
foreach($rows as $row) {
echo '<tr>';
echo '<td class="icon"><img class="artefact_icon_'.$row['type'].'" src="img/x.gif" alt="" title=""></td>';
echo '<td class="nam">';
echo ''.$row['name'].' <span class="bon">'.$row['effect'].'</span>';
echo '<div class="info">';
if($row['size'] == 1){
$reqlvl = 10;
$effect = "village";
}elseif($row['size'] == 2 OR $row['size'] == 3){
$reqlvl = 20;
$effect = "account";
}
echo '<div class="info">Treasury <b>'.$reqlvl.'</b>, Effect <b>'.$effect.'</b>';
echo '</div></td><td class="pla">'.$database->getUserField($row['owner'],"username",0).'</td>';
echo '<td class="dist">'.getDistance($coor['x'], $coor['y'], $coor2['x'], $coor2['y']).'</td>';
echo '</tr>';
}
?>
but the code seems to be wrong because its showing all same distances. 14.8 to me. I know i maybe have bad explanation but u will probably understand what I need.
I can't help with your current code I'm afraid but you could try using the Haversine Formula instead:
// Where:
// $l1 ==> latitude1
// $o1 ==> longitude1
// $l2 ==> latitude2
// $o2 ==> longitude2
function haversine ($l1, $o1, $l2, $o2) {
$l1 = deg2rad ($l1);
$sinl1 = sin ($l1);
$l2 = deg2rad ($l2);
$o1 = deg2rad ($o1);
$o2 = deg2rad ($o2);
$distance = (7926 - 26 * $sinl1) * asin (min (1, 0.707106781186548 * sqrt ((1 - (sin ($l2) * $sinl1) - cos ($l1) * cos ($l2) * cos ($o2 - $o1)))));
return round($distance, 2);
}
Credit goes to this post on go4expert.com, I've used this function in the past and found it works very well.
I've been working on getting a Coefficient of Variation equation ported from PHP to Javascript, but can't seem to get it working.
Original PHP script:
// define variables, strip spaces
$weights = $_POST['weights'];
// define coefficient of variation function
function cv($array){
$n = 0;
$mean = 0;
$M2 = 0;
foreach($array as $x){
if ($x != NULL AND $x != '') {
$n++;
$delta = $x - $mean;
$mean = $mean + $delta/$n;
$M2 = $M2 + $delta*($x - $mean);
$total = $total + $x;
}
}
return (((sqrt($M2/($n - 1))) / ($total/$n))*100);
}
$cv = (cv($weights));
This basically takes an array, and figures out the coefficient of variation for it. Now as I try to convert it to Javascript via some Jquery function:
var fields = $('#cvform').serializeArray();
var count = 0;
var num = 0;
var mean = 0;
var m2 = 0;
var total = 0;
var delta = 0;
jQuery.each(fields, function(i, field){
if (field.value > 0) {
num++;
delta=(field.value-mean);
mean=(mean+delta/num);
m2=(m2+delta*(field.value-mean));
total=(total+field.value);
};
});
var cov=(((Math.sqrt(m2/(num-1)))/(total/num))*100);
$("<span>Coefficient of Variation: " + cov + "</span>").appendTo('#cvdisplay');
While the javascript function outputs an answer, it is not correct. If I enter the values "3,3,2,3,3,4" the PHP script gives an output of 21.08, which is correct. The javascript function gives me the value of 0.0011418432035849642.
Can anyone point me to where the equations are differing?
You need to convert your array values to floats via parseFloat() (or integers, parseInt(), whatever suits you):
var fields = $('#cvform').serializeArray();
var count = 0;
var num = 0;
var mean = 0;
var m2 = 0;
var total = 0;
var delta = 0;
$.each(fields, function(i, field) {
alert(field.value);
if (parseFloat(field.value) > 0) {
num++;
delta = (parseFloat(field.value) - mean);
mean = (mean + delta / num);
m2 = (m2 + delta * (parseFloat(field.value) - mean));
total = (total + parseFloat(field.value));
}
});
var cov = (((Math.sqrt(m2 / (num - 1))) / (total / num)) * 100);
$("<span>Coefficient of Variation: " + cov + "</span>").appendTo('#cvdisplay');
The issue is the javascript line
total=(total+field.value); which results in 0332334 instead of 18 as expected. String concatenation is being applied instead of numeric addition.
You can fix this by parsing the integer value: total += parseInt(field.value);
function stDeviation(array){
var L= array.length,
mean= array.reduce(function(a, b){
return a+b;
})/L,
dev= array.map(function(itm){
var tem= itm-mean;
return tem*tem;
});
return Math.sqrt(dev.reduce(function(a, b){
return a+b;
})/L);
}
Math.mean= function(array){
return array.reduce(function(a, b){ return a+b; })/array.length;
}
Math.stDeviation=function(array){
var mean= Math.mean(array);
dev= array.map(function(itm){return (itm-mean)*(itm-mean); });
return Math.sqrt(dev.reduce(function(a, b){ return a+b; })/array.length);
}
var A2= [6.2, 5, 4.5, 6, 6, 6.9, 6.4, 7.5];
alert ('mean: '+Math.mean(A2)+'; deviation: '+Math.stDeviation(A2))
Here, I changed the code around a bit and got it to work. I basically isolated the segments a bit more. Made it more direct.
<?php
$weights = Array(3,3,2,3,3,4);
// define coefficient of variation function
function cv($array) {
$n = 0;
$mean = 0;
$M2 = 0;
$total = 0;
foreach($array as $x) {
if ( !empty($x) ) {
$n++;
$delta = $x - $mean;
$mean = $mean + $delta / $n;
$M2 = $M2 + $delta * ($x - $mean);
$total = $total + $x;
}
}
$sqrt = sqrt( $M2 / ($n - 1) );
$tn = $total / $n;
echo "Sqrt is $sqrt tn is $tn";
return ( $sqrt / $tn ) * 100;
}
$cv = cv($weights);
?>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var fields = Array(3,3,2,3,3,4);
var count = 0;
var n = 0;
var mean = 0;
var m2 = 0;
var total = 0;
var delta = 0;
jQuery.each(fields, function(i, field) {
//var x = field.value;
var x = 1 * field;
if (x > 0) {
n++;
delta = (x - mean);
mean = (mean + (delta / n));
m2 = (m2 + delta * (x - mean));
total = (total + x);
};
});
var sqrt = Math.sqrt(m2 / (n - 1));
var tn = total / n;
var cov = ((sqrt / tn) * 100);
console.log("Total is: "+ total);
console.log("Sqrt is " + sqrt + " tn is " + tn + " cov is " + cov);
$('#js').text("JS Output is: " + cov);
});
</script>
</head>
<body>
<div>
<div>PHP Output: <?=$cv;?></div>
<div id="js"></div>
</div>
</body>
</html>
Here's a direct translation of the function you provided. You have to pass in a javascript array of numbers, and it produces the result you're looking for (at least according to unit tests written in Node.js). You should to the type conversion (string-to-array) in another function to separate your concerns and make the code easier to reason about;
var CoV = function(ary) {
var mean = 0,
n = 0,
m2 = 0,
total = 0,
delta;
for(var i = 0, l = ary.length; i < l; i += 1) {
n += 1;
delta = ary[i] - mean;
mean = mean + delta / n;
m2 = m2 + delta * (ary[i] - mean)
total = total + ary[i]
}
console.log(mean);
console.log(m2);
console.log(total);
return ((Math.sqrt(m2/(i - 1))) / (total / i)) * 100;
};