Jump to navigation Jump to search

Hi. Has somebody an idear how to make this smaller. I need the max bearing difference between all enemys. My gut feeling says it should be easier, but i can't see it.

	private void calcBearingDiff()
		if (myScans.isEmpty()) return;
		Comparator<ATarget> compi = new Comparator<ATarget>() 
			public int compare(ATarget a, ATarget b) 
				double eAbsBearA = a.getBearing() + myRobot.getHeadingRadians();
				double eAbsBearB = b.getBearing() + myRobot.getHeadingRadians();
				return, eAbsBearB);
		ArrayList<ATarget> enemys = new ArrayList<ATarget>(myScans.values());
		Collections.sort(enemys, compi);
		ATarget last = null;
		for (ATarget target : enemys) 
			if (last != null) 
				double eAbsBearingA = last.getBearing() + myRobot.getHeadingRadians();
				double eAbsBearingB = target.getBearing() + myRobot.getHeadingRadians();
				double diff = Utils.normalRelativeAngle(eAbsBearingA - eAbsBearingB);	

	                        // .... sort out the max
			last = target;
Wompi11:06, 21 April 2012

Ah .. i'm looking for a different approach to the problem and not to make the code smaler.

Wompi11:19, 21 April 2012

Could make ATarget comparable

Chase-san18:30, 21 April 2012

Thanks Chase. ATarget is a comparable but for other stuff. What i was looking for was something around another data structur. The above code snippet is way to much code for my taste. I thougth about to register the next ATarget on every ATarget and then simple ask the difference but it didn't work very well because i had to reorder the references to much. I'm looking for something that can handle ... update ATarget ... sort out the closest (bearing) ATarget ... and give the difference back ... I think i have to find a appropriate List/Tree structure for this.

Wompi13:48, 23 April 2012

Hmmm... what are you trying to use this for? I don't think I quite understood the question. Are you trying to get the biggest angle between any two in consecutive radial order? Or the one which is the closest to 180 degrees from it?

Skilgannon16:46, 23 April 2012
Area Picture

Maybe this picture can explain what i need. As you can see the white lines are the absBearing to every enemy and the transparent white area is the area from the two enemys who have the widest bearing to each other. I need this for my radar and my movement.
And yes i need the biggest angle between two in radial order (i guess :)). Nevermind the blue and green lines they are for something else.

Wompi18:43, 23 April 2012

I'm not sure, that i correctly understood your question and that its algorithm is completely correct, but idea must work, i think

double minAbsBearing = Integer.MAX_VALUE;
double minRelBearing = Integer.MAX_VALUE;
double maxRelBearing = Integer.MIN_VALUE;

for (ATarget target : enemys) {
    double absBearing = ...; // me.angleTo(target) in my case
    double relBearing = Utils.normalRelativeAngle(absBearing);
    if (relBearing < minRelBearing) {
        minAbsBearing = absBearing;
        minRelBearing = relBearing;
    if (relBearing > maxRelBearing) {
        maxRelBearing = relBearing;

double widestArea = maxRelBearing - minRelBearing;
double startAngle = minAbsBearing;
double endAngle = Utils.normalAbsoluteAngle(minAbsBearing + widestArea);
Jdev07:20, 24 April 2012

You nailed it mate. Thanks. Looks like i was totaly looking at the wrong direction. But at least my gut was right :). Man this is even smaller than i hoped for.

Wompi10:26, 24 April 2012

You are welcome, but this code would not work:) Now I have no time to describe why (writing on english is difficult for me), but try to test different cases and you will easy understand the problem.

Jdev05:50, 25 April 2012

I also thought there might be some issues at certain angles with the single loop approach.

I think you need to take a <math>n^2</math> approach, ie, a loop within a loop. Otherwise you need to use a sorting technique (with nlogn), then a single loop. Here is pseudocode:

initialise min_sum = Inf
For each bot, b:
    me_b = find the angle from me to b
    initialise min_rel = Inf, max_rel = -Inf.
    for each bot c, excluding b:
        me_c = find the angle from me to c
        rel = the relative angle between me_b and me_c
        if rel < min_rel, min_rel = rel. if rel > max_rel, max_rel = rel.
    sum = max_rel - min_rel
    if sum < min_sum, min_sum = sum, min_ang = me_b + min_rel, max_ang = me_b + max_rel.

The other approach would be to sort all the angles into radial order, then go through looking for the largest space between two angles, and then use the opposite part of the circle. So in pseudocode:

for each bot, b:
    me_b = angle from me to b
    angles[i++] = me_b


max_rel = abs(relative_angle(angles[0] - angles[angles.length - 1]))
min_angle = angles[0]
max_angle = angles[angles.length-1]
max_index = 0
for(i = 1; i < angles.length; i++)
    rel = abs(relative_angles(angles[i-1] - angles[i]));
    if rel > max_rel
        max_rel = rel
        min_angle = angles[i]
        max_angle = angles[i-1]
        max_index = i
Skilgannon08:35, 25 April 2012

Yes Jdev you are right it does not work for all angles and i was aware of that. But it pushed me into another direction to think about it. If the bot stays almost ever on the edge or corner of the battlefield your code works very well i get some really impressive average visit counts with my radar.

Thanks Skilgannon your first approach looks interesting and i will give it a try. Haven't found the time for now. My first thougth to overcome the angle glitch was to throw in a signum() direction check and switch the angles if they don't fit. Don't know how to describe this and its again more of my gut feeling which tells me that this might work. I'm almost sure i did this once but lost it. The second one looks a little like my first try, not really sure about that to.

But anyway, thanks to both of you for bringing me out of my stubborn mind state.

Wompi15:00, 25 April 2012