Joe JJJ
Joe JJJ

Reputation: 25

Can't understand why my php cosine similarity code isn't working

I'm working on a website for my friend's gaming clan. I'm trying to have a php code that takes the player's coordinates, loops over some known locations and print the name of the closest location.

I can't get it to work however. It always seems to want to print "Balota" which is index 1 in the array. I also noticed that the cosine function can't be working as all values are above 1.0.

But I'm completely stuck now. I think I've been beating my head over it for too long and its something right in front of me but I can't see it.

<?php


function DotProd($loc1,$loc2){
    return array_sum(array_map(create_function('$a, $b', 'return $a * $b;'), $loc1, $loc2));
}
function CosineSim($loc1,$loc2){
    return DotProd($loc2,$loc2)/sqrt(DotProd($loc1,$loc2)*DotProd($loc1,$loc2));
}
function Closest($loc){
    $novo = array(11300,14300);
    $balota = array(4500,2500);
    $zelen = array(2500,5200);
    $sever = array(7900,12600);
    $vybor = array(4500,8200);
    $nwaf = array(4500,10200);
    $neaf = array(12100,12500);
    $kamensk = array(7870,14600);
    $bere = array(12900,10000);
    $gorka = array(9600,8900);
    $elektro = array(10100,2000);
    $cherno = array(6600,2600);
    $stary = array(6100,7700);
    $novy = array(7000,7700);
    $mysk = array(1100,7200);

    $locations = array($novo,$balota,$zelen,$sever,$vybor,$nwaf,$neaf,
        $kamensk,$bere,$gorka,$elektro,$cherno,$stary,$novy,$mysk);

    $sim = 99999999999;
    $locat = 0;
    for($i = 14; $i >= 0; $i--){
        $s = CosineSim($loc,$locations[$i]);
        echo    "<br>" . $i . " " . CosineSim($loc,$locations[$i]);
        if($s < $sim){
            $sim = $s;
            $locat = $i;
        }
    }
    $items = array("Novo","Balota","Zelenogorsk","Severograd","Vybor","NWAF","NEAF","Kamensk Military","Berezino",
                        "Gorka","Elektro","Cherno","Stary Sobor","Novy Sobor","Myshkino");
    return $items[$locat];
}
$x = $_GET["xpos"];
$y = $_GET["ypos"];


$location = array($x,$y);


echo "<b>You are at " . $x . ":" . $y; 
$index = Closest($location);
echo "<br>You're pretty close to ". $index . "<br>";

?>

Upvotes: 0

Views: 345

Answers (1)

jasonwubz
jasonwubz

Reputation: 361

I am using a distance calculation formula based on the link: https://www.mathwarehouse.com/algebra/distance_formula/index.php

I only changed CosineSim. The rest of the code remains the same. And you don't actually need DotProd. It's not elegant but it works for me.

function CosineSim($loc1,$loc2){
    // sum of x coordinates
    $x1 = ($loc1[0]-$loc2[0])*($loc1[0]-$loc2[0]);

    // sum of y coordinates
    $y2 = ($loc1[1]-$loc2[1])*($loc1[1]-$loc2[1]);

    $summ = $x1 + $y2;
    $sqrt_res = sqrt($summ);
    return $sqrt_res;
}

If I enter something like:

You are at 4640:7205
...
You're pretty close to Vybor

Hope this helps!

Upvotes: 1

Related Questions