Discussion What is the most efficient way to crowdsource the 3D system coordinates

wolverine2710

Tutorial & Guide Writer
Ah, but I was proposing server-side mediated completion, where it'll autofill with any star name it knows. This way people can benefit from others having already entered star names (hopefully accurately).

If you're using the same set of stars as references for each new source star it'd be nice if they were easy to fill in, yes ?

There is a slight concern with the number of stars ballooning and making this a little clunky, but a little RESTful API to it with the server set to use some compression will mean no bandwidth worries, and I'd hope anyone playing the game has a machine capable of doing quick lookups on an array of even 200,000 elements....

The basic point is to make the data entry as easy as we possibly can so that people don't feel it's too much of a chore. Encourage as much data as possible!

I agree that server-side completion would be the icing on the cake. A simple Ajax Jquery could do the trick. Using ajax you send the current partially typed name to the server (where all 200.000 systems live) and receive a suggestion. BUT this only has to be done for the single 'current system' input field. The 9 destination input field have their name hard coded in the form and a commander only need to input distance numbers there - read from the galaxy map.

And YES making data entry as simple and convenient as possible is the key to make sure there will be potentially lots more commanders inputting there distance numbers. Especially crucial when they open up the Galaxy more. But I hope FD will be able to supply us with more numbers in the future. If done by one or two commanders its time consuming. If done by 50+ we have the coordinates for SB2 (and later SB3 etc) in no time.
 

wolverine2710

Tutorial & Guide Writer
Sorry for only coming into this discussion so late, I only picked up the thread now.

I have the calcs for quadrangulating the coords as well, (using a different approach, I think), I am happy to share this with you, and also to contribute to the crowd sourcing.

I'm at work at the moment, but will see what I can do about uploading data this evening or tomorrow.

WELCOME commander. Looking forward to your data and for willing to aid in the crowd sourcing effort.
 

wolverine2710

Tutorial & Guide Writer
I did sent a PM to Michael Brookes this morning about the 1/32 LY grid issue. I've got a very fast response. Not totally sure how to interpret it and don't want to waste his time. So before I send a reply to him perhaps the collected minds here can decypher/interpret what he wrote. BUT it looks as if a 1/32LY grid is NOT being used all the time!!

Question: " Is the stellar forge using a 1/32LY grid?"
Hello Mr Brookes,

You have supplied me/the community with a list of 307 star systems which have a station - again thanks for that. SB2 has 507 systems. As part of a crowd sourcing effort to get the rest of the coordinates the data supplied by you has been analyzed and questions were raised. It seems as if the stellar forge algorithm is using a 1/32LY grid to place the systems on. It has been described better here and in a few posts before that. If true the calculated coordinates should be adjusted to fit into a 1/32LY grid.

My question: Would it be possible for you to relay this question to a dev so (s)he can confirm/deny this. That would be very much appreciated.

With kind regards,
Jan Bessels

Answer:
Michael Brookes: "It uses multiple sized grids depending on the mass of the star being generated."
 
Last edited:
I did sent a PM to Michael Brookes this morning about the 1/32 LY grid issue. I've got a very fast response. Not totally sure how to interpret it and don't want to waste his time. So before I send a reply to him perhaps the collected minds here can decypher/interpret what he wrote. BUT it looks as if a 1/32LY grid is NOT being used all the time!!

Question: " Is the stellar forge using a 1/32LY grid?"
Hello Mr Brookes,

You have supplied me/the community with a list of 307 star systems which have a station - again thanks for that. SB2 has 507 systems. As part of a crowd sourcing effort to get the rest of the coordinates the data supplied by you has been analyzed and questions were raised. It seems as if the stellar forge algorithm is using a 1/32LY grid to place the systems on. It has been described better here and in a few posts before that. If true the calculated coordinates should be adjusted to fit into a 1/32LY grid.

My question: Would it be possible for you to relay this question to a dev so (s)he can confirm/deny this. That would be very much appreciated.

With kind regards,
Jan Bessels

Answer:

I think the 1/32 ly thing, together with what wtbw found about how the co-ordinates are actually held by the game, points to them being held as single-precision floating point, or at least what Michael Brookes used to extract them was limited to that.

What I saw is that ~Eranin co-ordinates internally are 50000, 41000, 24000, which means counting from 'left'/'behind'/'below' as the internal origin. These in-game are close enough to the origin to use that... and I know it's something like 100,000 LY to the far side of the galaxy from there.

If we put 150000.01325 (decimal part is 1/32) into binary we get 100100100111110000.00001000000000000 - which is 19 bits before the binary point and 5 after to the '1'. That's 24 bits total, which matches the description of the Significand for Single Precision on http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
 
I did sent a PM to Michael Brookes this morning about the 1/32 LY grid issue. I've got a very fast response. Not totally sure how to interpret it and don't want to waste his time.

I think Michael may not have interpreted your question as it was intended.

I think the 1/32 ly thing, together with what wtbw found about how the co-ordinates are actually held by the game, points to them being held as single-precision floating point, or at least what Michael Brookes used to extract them was limited to that.

Assuming the 1/32 Ly precision is not an artifact of the extraction process, I think it's more likely that ED uses a custom fixed point format for system coordinates. This is something Braben did in Frontier and FFE (he also used a custom floating point format in those games). There's no real reason to do that with current hardware but it wouldn't surprise me if they did.
 
I would be perfectly happy with in game coords displayed on system map with 2 or 3 digits precision. The 1/32 discussion is to me pointless. For practical route planning it just doesnt matter if your spreadsheet happens to be 0.001 off the in game coords.
 
I would be perfectly happy with in game coords displayed on system map with 2 or 3 digits precision. The 1/32 discussion is to me pointless. For practical route planning it just doesnt matter if your spreadsheet happens to be 0.001 off the in game coords.

The discussion may be pointless to you but some people may be more interested in it as an abstract problem than for practical route planning. It's not pointless to them.

For practical purposes knowing that systems are constrained to coordinates in steps of 1/32 allows for extra error checking.
 
I'm still trying to work out a JavaScript or c# implementation of the trilateration function for the route planner on my site, the maths is horrible. :D
 
The discussion may be pointless to you but some people may be more interested in it as an abstract problem than for practical route planning. It's not pointless to them.

For practical purposes knowing that systems are constrained to coordinates in steps of 1/32 allows for extra error checking.

The OP is not about the abstract problem. Wasting CPU-cycles on anything but 4 distances from known coordinates make polar bears cry.
 

wolverine2710

Tutorial & Guide Writer
The OP is not about the abstract problem. Wasting CPU-cycles on anything but 4 distances from known coordinates make polar bears cry.

Iirc it has been discussed here and agreed upon that taking more then 4 distances (can) enhance the acccuracy and/or be used to detect faulty entered data. If you have a source that states otherwise I (and I assume others) would be very interested in this.
 
I'm still trying to work out a JavaScript or c# implementation of the trilateration function for the route planner on my site, the maths is horrible. :D

I've written a javascript implementation that works for the one point I've tested it on ;) I have some enhancements planned but you can have a copy if you want.
 
I'm still trying to work out a JavaScript or c# implementation of the trilateration function for the route planner on my site, the maths is horrible. :D

Here is my php implementation, should be easy enough to rewrite to JS or C#
Code:
function trilateration3d($p1,$p2,$p3,$p4){
        $ex = vector_unit(vector_diff($p2, $p1));
        $i = vector_dot_product($ex, vector_diff($p3, $p1));
        $ey = vector_unit(vector_diff(vector_diff($p3, $p1), vector_multiply($ex, $i)));
        $ez = vector_cross($ex,$ey);
        $d = vector_length($p2, $p1);
        $r1 = $p1[3]; $r2 = $p2[3]; $r3 = $p3[3]; $r4 = $p4[3];
        if($d - $r1 >= $r2 || $r2 >= $d + $r1){
                return array();
        }
        $j = vector_dot_product($ey, vector_diff($p3, $p1));
        $x = (($r1*$r1) - ($r2*$r2) + ($d*$d)) / (2*$d);
        $y = ((($r1*$r1) - ($r3*$r3) + ($i*$i) + ($j*$j)) / (2*$j)) - (($i*$x) / $j);
        $z = $r1*$r1 - $x*$x - $y*$y;

        if($z < 0){
                return array();
        }
        $z1 = sqrt($z);
        $z2 = $z1 * -1;

        $result1 = $p1;
        $result1 = vector_sum($result1, vector_multiply($ex, $x));
        $result1 = vector_sum($result1, vector_multiply($ey, $y));
        $result1 = vector_sum($result1, vector_multiply($ez, $z1));
        $result2 = $p1;
        $result2 = vector_sum($result2, vector_multiply($ex, $x));
        $result2 = vector_sum($result2, vector_multiply($ey, $y));
        $result2 = vector_sum($result2, vector_multiply($ez, $z2));

        $r1 = vector_length($p4, $result1);
        $r2 = vector_length($p4, $result2);
        $t1 = $r1 - $r4;
        $t2 = $r2 - $r4;
        $coords = array();
        if(abs($t1) < abs($t2)){
                $coords = array(round($result1[0], 5), round($result1[1], 5), round($result1[2], 5));
        }
        else{
                $coords = array(round($result2[0], 5), round($result2[1], 5), round($result2[2], 5));
        }
        return $coords;
}

function vector_length($p1, $p2){
        $a1 = $p1[0];
        $a2 = $p2[0];
        $b1 = $p1[1];
        $b2 = $p2[1];
        $c1 = $p1[2];
        $c2 = $p2[2];
        $dist = sqrt((($a2-$a1)*($a2-$a1))+(($b2-$b1)*($b2-$b1))+(($c2-$c1)*($c2-$c1)));

        return round($dist, 3, PHP_ROUND_HALF_EVEN);
}

function vector_sum($v1, $v2){
        $v = array();
        $v[0] = $v1[0] + $v2[0];
        $v[1] = $v1[1] + $v2[1];
        $v[2] = $v1[2] + $v2[2];
        return $v;
}

function vector_cross($v1, $v2){
        $v = array();
        $v[0] = ($v1[1] * $v2[2]) - ($v1[2] * $v2[1]);
        $v[1] = ($v1[2] * $v2[0]) - ($v1[0] * $v2[2]);
        $v[2] = ($v1[0] * $v2[1]) - ($v1[1] * $v2[0]);
        return $v;
}

function vector_multiply($v, $i){
        return array($v[0] * $i, $v[1] * $i, $v[2] * $i);
}

function vector_dot_product($v1, $v2){
        $ret = ($v1[0] * $v2[0]) + ($v1[1] * $v2[1]) + ($v1[2] * $v2[2]);
        return $ret;
}

function vector_diff($p1,$p2){
        $ret = array($p1[0] - $p2[0], $p1[1] - $p2[1], $p1[2] - $p2[2]);
        return $ret;
}

function vector_norm($v){
        $l = sqrt(($v[0]*$v[0])+($v[1]*$v[1])+($v[2]*$v[2]));
        return $l;
}

function vector_div($v, $l){
        return array($v[0]/$l, $v[1] / $l, $v[2] / $l);
}

function vector_unit($v){
        $l = vector_norm($v);
        if($l == 0){
                return -1;
        }
        return vector_div($v, $l);
}
 
The OP is not about the abstract problem. Wasting CPU-cycles on anything but 4 distances from known coordinates make polar bears cry.

What do I care about polar bears? I'm not even in the same hemisphere!

Since we only have 2 or 3 decimal places in the distance data the errors can be significant if the 4 chosen points are not optimally arranged.
 
Wouldn't it be more efficient as a stored procedure? Keep it in the db!

It definitely wouldn't be more efficient as a stored procedure, but that wouldn't matter for the volume of calculation we're talking about. Implementing it in the database is not unreasonable, though personally I probably wouldn't use an RDBMS for this, I'd use something like Redis.
 

Harbinger

Volunteer Moderator
Here is my php implementation, should be easy enough to rewrite to JS or C#


Can you give a usage example for your script?

EDIT: Never mind I figured it out. ;)

Code:
<?php

// Testing from Eranin. Actual coordinates: -22.843750, 36.531250, -1.187500

$system1=array(-23.937500, 40.875000, -1.343750, 4.482); // Asellus Primus
$system2=array(-26.781250, 37.031250, -4.593750, 5.230); // LP 98-132
$system3=array(-22.375000, 34.843750, 4.000000, 5.475); // i Bootis
$system4=array(-19.750000, 41.781250, -3.187500, 6.414); // Dahan

echo "<pre>";
print_r(trilateration3d($system1, $system2, $system3, $system4));
echo "</pre>";

function trilateration3d($p1,$p2,$p3,$p4){
        $ex = vector_unit(vector_diff($p2, $p1));
        $i = vector_dot_product($ex, vector_diff($p3, $p1));
        $ey = vector_unit(vector_diff(vector_diff($p3, $p1), vector_multiply($ex, $i)));
        $ez = vector_cross($ex,$ey);
        $d = vector_length($p2, $p1);
        $r1 = $p1[3]; $r2 = $p2[3]; $r3 = $p3[3]; $r4 = $p4[3];
        if($d - $r1 >= $r2 || $r2 >= $d + $r1){
                return array();
        }
        $j = vector_dot_product($ey, vector_diff($p3, $p1));
        $x = (($r1*$r1) - ($r2*$r2) + ($d*$d)) / (2*$d);
        $y = ((($r1*$r1) - ($r3*$r3) + ($i*$i) + ($j*$j)) / (2*$j)) - (($i*$x) / $j);
        $z = $r1*$r1 - $x*$x - $y*$y;

        if($z < 0){
                return array();
        }
        $z1 = sqrt($z);
        $z2 = $z1 * -1;

        $result1 = $p1;
        $result1 = vector_sum($result1, vector_multiply($ex, $x));
        $result1 = vector_sum($result1, vector_multiply($ey, $y));
        $result1 = vector_sum($result1, vector_multiply($ez, $z1));
        $result2 = $p1;
        $result2 = vector_sum($result2, vector_multiply($ex, $x));
        $result2 = vector_sum($result2, vector_multiply($ey, $y));
        $result2 = vector_sum($result2, vector_multiply($ez, $z2));

        $r1 = vector_length($p4, $result1);
        $r2 = vector_length($p4, $result2);
        $t1 = $r1 - $r4;
        $t2 = $r2 - $r4;
        $coords = array();
        if(abs($t1) < abs($t2)){
                $coords = array(round($result1[0], 5), round($result1[1], 5), round($result1[2], 5));
        }
        else{
                $coords = array(round($result2[0], 5), round($result2[1], 5), round($result2[2], 5));
        }
        return $coords;
}

function vector_length($p1, $p2){
        $a1 = $p1[0];
        $a2 = $p2[0];
        $b1 = $p1[1];
        $b2 = $p2[1];
        $c1 = $p1[2];
        $c2 = $p2[2];
        $dist = sqrt((($a2-$a1)*($a2-$a1))+(($b2-$b1)*($b2-$b1))+(($c2-$c1)*($c2-$c1)));

        return round($dist, 3, PHP_ROUND_HALF_EVEN);
}

function vector_sum($v1, $v2){
        $v = array();
        $v[0] = $v1[0] + $v2[0];
        $v[1] = $v1[1] + $v2[1];
        $v[2] = $v1[2] + $v2[2];
        return $v;
}

function vector_cross($v1, $v2){
        $v = array();
        $v[0] = ($v1[1] * $v2[2]) - ($v1[2] * $v2[1]);
        $v[1] = ($v1[2] * $v2[0]) - ($v1[0] * $v2[2]);
        $v[2] = ($v1[0] * $v2[1]) - ($v1[1] * $v2[0]);
        return $v;
}

function vector_multiply($v, $i){
        return array($v[0] * $i, $v[1] * $i, $v[2] * $i);
}

function vector_dot_product($v1, $v2){
        $ret = ($v1[0] * $v2[0]) + ($v1[1] * $v2[1]) + ($v1[2] * $v2[2]);
        return $ret;
}

function vector_diff($p1,$p2){
        $ret = array($p1[0] - $p2[0], $p1[1] - $p2[1], $p1[2] - $p2[2]);
        return $ret;
}

function vector_norm($v){
        $l = sqrt(($v[0]*$v[0])+($v[1]*$v[1])+($v[2]*$v[2]));
        return $l;
}

function vector_div($v, $l){
        return array($v[0]/$l, $v[1] / $l, $v[2] / $l);
}

function vector_unit($v){
        $l = vector_norm($v);
        if($l == 0){
                return -1;
        }
        return vector_div($v, $l);
}

?>

Output:
Code:
Array
(
    [0] => -22.84408
    [1] => 36.53124
    [2] => -1.18729
)

It's out by a small margin but I merely chose the 4 closest points in the navigation tab. I'm sure it would be more accurate with more points of reference.

Thanks for sharing this script. I'm going to try and modify it to provide a more accurate result.
 
Last edited:

wolverine2710

Tutorial & Guide Writer
It's out by a small margin but I merely chose the 4 closest points in the navigation tab. I'm sure it would be more accurate with more points of reference.

Thanks for sharing this script. I'm going to try and modify it to provide a more accurate result.

Saturday I did some flying and stopped by in dziban, nltt 44050, LHS 6354
Wredguia xx-o and B47-2. I took the distances to the 9 refence points suggested by Chromatix. These are Sol, Flousop, Tring, Rahu, Parcae, Hepa, Poqomathi, Hyperion and Aulin. You can find the result in the Codec spreadsheet.

I'm very curious how much the accuracy changes when taking 4,5,6,7,8,9 reference points into account. Of course under the assumption that I didn't make an error when entering the data.
 

Harbinger

Volunteer Moderator
I'm very curious how much the accuracy changes when taking 4,5,6,7,8,9 reference points into account. Of course under the assumption that I didn't make an error when entering the data.

I'm currently working on just that. I'm not messing about with the core function which gets passed 4 values though.

Instead I'm attempting to make it run all possible unique permutations if there are more than 4 systems entered (up to 126 for 9 points of reference) and then average out the values from all results to see how accurate the resulting coordinates are. I've already found a suitable function for outputting all the possible permutations so it shouldn't take long to code the rest.
 
Last edited:
Back
Top Bottom