3

This is rather conceptual, and I'm hoping someone can help. I have a script, that when you insert coordinates (x,y, from 0 -> 800) in to it, it'll return lists of pre-plotted coordinates that are within 3 separate ranges.

ie: I enter 200,200. I receive a list for each of the following: Plots that are within a radius of 25, a radius of 60, a radius of 150.

The code if you're curious / for context:

        display(coords[n][1] + ", " + coords[n][2]);

    if(n==0){

    for(var i=0; i < data.length; i++) {
        var xs = 0;
        var xy = 0;
        xs = xPlot - data[i][0];
        ys = yPlot - data[i][1];
        xs = xs * xs;
        ys = ys * ys;

        distance = Math.sqrt(xs + ys);

        if (distance <= 25){
            display2(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
        else if(distance <= 60){
            display3(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
        else if(distance <= 150){
            display4(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
    }

Easy enough.

Now, when I input another set of coordinates another multidimensional array is created, I want to check for intersecting points within the two (well, 6) circles.

I thought of using an array for my checking. If 2 coords are entered, and a point is found within both inner (green) circles, a = [g,g]. If a point is found within an inner of one, but a mid (blue) of the other, set a = [g,b] You get the idea. Red being the outer circle.

When 3 coords are entered things get trickier. Let's say a point is within two inners, and one mid. Then a = [g,g,b]. The purpose of the 3 lists, is to organize the returned values in groups of best to worst. So in an example with 4 inputs, the lists are to be organised in the following way:

List 1 / List 2 / List 3
gggg / gggb / bbbr
------- / ggbb / bbrr
------- / gbbb / brrr
------- / bbbb / rrrr

How would I build check my array in a scalable way so if I had 5 inputs, I'd be able to place my results in the appropriate columns?

I've started with this sofar:

else if(n>0){

    for(var i=0; i < data.length; i++) {
        for(var j=0; j < coords.length; j++) {
            var xs = 0;
            var ys = 0;
            xs = coords[j][1] - data[i][0];
            ys = coords[j][2] - data[i][1];
            xs = xs * xs;
            ys = ys * ys;
            distance = Math.sqrt(xs + ys);

            if (distance <= 25){
                a[j] = [,[g]];
                }
            else if (distance <= 60){
                a[j] = [,[b]];
                }
            else if (distance <= 150){
                a[j] = [,[r]];
                }
        }
        if($.inArray('g', a) && (!($.inArray('b', a)))){
            display2(data[i][0] + ", " + data[i][1] + " - " + alliance);

}

Would this last line execute if a contained g, but NOT b?? (jquery) Am I on the right track?

lunchtime
  • 55
  • 5
  • Seems like some of [this guy's repos](https://github.com/kriskowal) might be useful, especially es5-shim and Montage Collections. I'm sure somebody out there has an array.intersect. – Jared Farrish Jan 13 '13 at 01:41

2 Answers2

3

Instead of putting the occurance inside a circle as an item in an array, count the number of occurances in an array with the same length as the number of circles. I.e. instead of [g,g,g,g,b,b,r,r,r,r,r,r,r], use [4,2,7]. That way you don't have to keep the array sorted when adding items, you just increment the correct item.

That also makes it easy to sort the result on relevance. You can create a numeric value for the array by looking at it as a number with the base being the same as the number of data coordinates. I.e.:

var n = arr[0] * data.length * data.length + arr[1] * data.length + arr[2];

With 10 data coordinates, the array [4,2,7] would get the value 427, making it easy to compare it to the array [3,5,0] that would get the value 350.

You can calculate the arrays as:

for(var i=0; i < coords.length; i++) {
  var arr = [0, 0, 0];
  for(var j=0; j < data.length; j++) {
    var xs = coords[i][1] - data[j][0];
    var ys = coords[i][2] - data[j][1];
    distance = Math.sqrt(xs * xs + ys * ys);
    if (distance <= 25) {
      arr[0]++;
    } else if (distance <= 60) {
      arr[1]++;
    } else if (distance <= 150) {
      arr[2]++;
    }
  }
  coords[i].arr = arr;
  coords[i].value = arr[0] * data.length * data.length + arr[1] * data.length + arr[2];
}

Now you can sort the coordinates on the values:

coords.sort(function(a, b){
  return a.value - b.value;
});
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Although this is a very clever way to approach it, it doesn't quite utilize what I need, since in the end of everything I want to print out the coordinates that are found. I solved my problem with a bit of wine, and some booleans. – lunchtime Jan 13 '13 at 03:20
0

Here's the solution I came up with. It does exactly what I need, while displaying the coordinates that are found in their proper places.

http://pastehtml.com/view/cowibn4bs.html to see the fruits of my labour.

if(n==0){

    for(var i=0; i < data.length; i++) {
        var xs = 0;
        var xy = 0;
        xs = xPlot - data[i][0];
        ys = yPlot - data[i][1];
        xs = xs * xs;
        ys = ys * ys;

        distance = Math.sqrt(xs + ys);

        if (distance <= 25){
            display2(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
        else if(distance <= 60){
            display3(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
        else if(distance <= 150){
            display4(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
    }
    }

    else if(n>0){

    $('#msgs2').html('');
    $('#msgs3').html('');
    $('#msgs4').html('');


    for(var i=0; i < data.length; i++) {
        a = [];
        for(var j=0; j < coords.length; j++) {
            var xs = 0;
            var ys = 0;
            xs = coords[j][1] - data[i][0];
            ys = coords[j][2] - data[i][1];
            xs = xs * xs;
            ys = ys * ys;
            distance = Math.sqrt(xs + ys);

            if (distance <= 25){
                a[j] = 'g';
                }
            else if (distance <= 60){
                a[j] = 'b';
                }
            else if (distance <= 150){
                a[j] = 'r';
                }
            else{
                a[j] = 0;
            }

        }
        if($.inArray(0, a) > -1){
        }
        else if($.inArray("g", a) > -1 && $.inArray("b", a) === -1){
            if($.inArray("r", a) === -1){
                display2(data[i][0] + ", " + data[i][1] + " - " + alliance);
            }
        }
        else if($.inArray("b", a) > -1 && $.inArray("r", a) === -1){
            display3(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
        else if($.inArray("r", a) > -1){
            display4(data[i][0] + ", " + data[i][1] + " - " + alliance);
        }
    }               

    }
    n++;
lunchtime
  • 55
  • 5
  • I can't find that you are doing any sorting there at all? The points are just displayed in the order that you put them in the array initially. – Guffa Jan 13 '13 at 03:46
  • http://pastehtml.com/view/cowibn4bs.html To see the fruits of my labour. The DISPLAY functions throw the coords up in the divs. – lunchtime Jan 13 '13 at 04:22
  • If the list only contains a single point, you can't see if it's sorted or not. – Guffa Jan 13 '13 at 05:04
  • Did you look at the link? It's totally dependent on the values entered within a web form, and checks points within the plotted circles. – lunchtime Jan 13 '13 at 06:08
  • Yes, I did, and I tried it out. It only handles one point. If you enter a new point it removes the result from the first and only shows the result for the second. – Guffa Jan 13 '13 at 06:09
  • Negative. It gives a collection between the two points. Insert X = 200, Y = 170 the first time around, then X = 200, Y = 200 the second time. You'll see the changes. It's working perfectly, and exactly how I wish it to :) the point "191, 189" on entering the second set of coords is the only one between the two green circles. Voila! – lunchtime Jan 13 '13 at 06:11
  • The lists is only showing the points that are within all the circles or that color, that's not what you specified. – Guffa Jan 13 '13 at 06:21
  • If a point ends up being in 1 green circle but in blue for a second coordinate, it gets added to the blue list. This is because the ideal target will be within two intersecting green circles. On the next level if you're using 3 coordinates, a point within two blues and red on the third gets tossed in the final list, since it is not ideal to coordinate against. This is a tool for people to use and determine an optimal 'target' between multiple allies in an RTS game. – lunchtime Jan 13 '13 at 07:03
  • Yes, I see that, but that's not what you specified in the question. There you put a point in the second list even if it's only in a single blue circle, not all blue circles. – Guffa Jan 13 '13 at 07:07