[Home]TrigChallenges

Robo Home | Changes | Preferences | AllPages

Like all Robocoders, I am frequently faced with trig challenges when implementing a new algorithm for my robot. Sometimes i am able to solve them myself, but some remain unsolved. I hope the latter categorie of challenges can be met by the trig guru's that visit this site :-)

note: i am not a trig expert and some of my calculations may be wrong :-) So, it would be useful if some of you trig guru's could check my solutions.

Feel free to add more challenges (with solution or open) to this page. good luck! -- Vic



1: how do i calculate the angle 'a' in a circle with radius 'r', given the arc length 'arcd'?

2: how do i calculate the angle 'a' in a circle with radius 'r', given the chord 'd'?




3: how do i calculate point p1(x1, y1), given angle 'a', center p0(x0, y0) and radius 'r'?

4: how do i calculate radius r, given point p1(x1, y1) and center p0(x0, y0)?

5: how do i calculate angle 'a', given point p1(x1, y1) and center(x0, y0)?

double calcAbsoluteAngle(double x0, double y0, double x1, double y1)
{
     return Math.atan2(x1-x0, y1-y0);
} 




how do i calculate the point p2 (x2,y2), given angle 'a', center(x0, y0) and point p1 (x1,y1)?




how do i calculate angle 'a', given a non rotating square B1 defined by center P1 (x1, y1) and width 'w', and center(x0,x1)?

-- FnH

A rough calculation is;

-- SSO?

Solving exactly would require you first select which two points on the square are deciding the angle -- there are 6 possibilities. That part is easy. Then, it just becomes a law of cosines problem. Alternatively, you could calculate the angle for all 6 possible combinations and choose the largest one. -- nano

ok got it.. FnH took a shot at nano's second option so i'll take one at the first:

///////////////////////////////
// first of all, determine which two corners define the projected angle:
//////////////////////////////

xmin = x1 - w/2;
xmax = x1 + w/2;
ymin = y1 - w/2;
ymax = y1 + w/2;

if(y0 >= ymin && y0 <= ymax)			//if p0 in horizontal bar defined by B1
{
	if (x0 < xmin)				//choose left or right corners"
	{
		corner_1.set(xmin, ymin);
		corner_2.set(xmin, ymax);
	}
	else
	{
		corner_1.set(xmax, ymin);
		corner_2.set(xmax, ymax);
	}
}
else if(x0 >= xmin && x0 <= xmax)		//else if p0 in vertical bar defined by B1
{
	if (y0 < ymin)				//choose top or bottom corners"
	{
		corner_1.set(xmin, ymin);
		corner_2.set(xmax, ymin);
	}
	else
	{
		corner_1.set(xmin, ymax);
		corner_2.set(xmax, ymax);
	}
}
else						//or else opposing corners define the angle"
{
	if(x0 < xmin)
	{
		furthest_x = xmax;
		 closest_x = xmin;
	}
	else
	{
		furthest_x = xmin;
		 closest_x = xmax;
	}

	if(y0 < ymin)
	{
		furthest_y = ymax;
		 closest_y = ymin;
	}
	else
	{
		furthest_y = ymin;
		 closest_y = ymax;
	}
	
	corner_1.set = (furthest_x,  closest_y);
	corner_2.set = ( closest_x, furthest_y);
}

///////////////////////////////
// then, using the law of cosine, calculate the angle:
//////////////////////////////

La = distance(p0, corner_1);
Lb = distance(p0, corner_2);
Lc = distance(corner_1, corner_2);

//law of cosine: Lc^2 = La^2 + Lb^2 ? 2 * La * Lb * cos(angle).
//therefore: cos(angle) = (Lc^2 - (La^2 + Lb^2)) / (- 2 * La * Lb)
//therefore: angle = acos ((Lc^2 - (La^2 + Lb^2)) / (- 2 * La * Lb))

a = Math.acos ((Lc * Lc - (La * La + Lb * Lb)) / (- 2 * La * Lb));

-- Vic Stewart




6. how do i calculate the maximum angle 'a' given bullet power 'Bp' and Robot velocity 'vR' (assuming instantaneous max speed and direction of the robot)

because here: -- atan(vR/vB is correct if the cord comes in so that the right angle is between vR and vB. This cord gives a smaller angle, the cord drawn gives a larger angle, it is the optimal value of the angle the opponent moves at to get the greatest angle. I think the page on NanoLauLectrik discusses this. -- Kawigi

-- I don't get the same results here, Kawigi. if I do atan(8/11) I get a=36 degrees. What am I doing wrong? How do I get this 46.7 degrees result? anyone? --Vic
-- It's not the atan(8/11), because the bullet trajectory is the hypotenuse of the triangle, not the line between you and the target (because that line would miss :-p), so it's the asin(8/11). The point being that they can get that far still before the bullet has traveled long enough to hit them. -- Kawigi
-- Ok, thanx. --Vic



7. how do i calculate the point p2 defined as the intersection of circle C and Line L given radius r, center p0(x0,y0) and point p1(x1,y1)



Given a origin point and a bearing from the point (Robocode style - 0 up, +ve clockwise) to generate a line that extends both sides of the origin point how do you calculate the perpendicular distance from the line of any other point so that you get positive distances for points to the right of the line (facing in the direction of the bearing) and negative distances for those points on the left of the line. Thanks Paul Evans.

I'm not sure I fully understand the question. But maybe this?

relativeBearing = normalRelativeAngle(bearingFromOriginToAnyPoint - lineBearing);
-- PEZ

Good approach to it - if you want the actual distance, it would be the sine of the above times the distance to the other point. -- Kawigi

Thanks - it's so obvious (but I could not sort it out) Paul Evans

Making a left/right stat segmenter? -- Kuuran

Nah - just trying to rate different points for Melee movement. -- Paul Evans

Seems like you'd do that with LateralVelocity instead. -- Kawigi

Isn't that basically what this is, just relative to a different system? -- Kuuran

Nah, it's distance, velocity needs a time component. If it's a left/right segmenter I'd rather use LateralVelocity or

bearingDelta = normalRelativeAngle(newBearing - oldBearing)
-- PEZ

You're right, of course. -- Kuuran

It seems like lateral velocity would be better than bearingDelta in a few cases, when your movement influences the bearingDelta more (and in the opposite direction) than the opponent's movement. But they'd have the same sign about 90% of the time. -- Kawigi

Any examination of magnitude is automatically wrong, though. -- Kuuran

(Refering to Kawigis' alert about bearingDelta.) Yes, if you just go with the bearings as reported by your radar. (That's why my very first attempts with AngularTargeting failed so brutally.) But done right I think it maybe better removes your own movement than lateralVelocity. If you check some of my bot code published here on the wiki you'll find that I calculate it like so:

oldBearing = bearing(myOldPosition, enemyOldPosition);
newBearing = bearing(myOldPosition, enemyNewPosition);
Which, of course, could be exactly what Pauls more general description is about. It also serves to illustrate that, if you're like me and don't know much trig at all, using coordinates for about everything is the way to go. -- PEZ


btw, visit the Trigonometry page for more resources.

Quick note: All of the trig being done is using robocode trigonometry, or at least should be. Not all of this is applicable in normal unit circle trig, though often replacing instances of 'sin' with 'cos' would fix it, and some of the trig being done isn't dependent on robocode trig as it analyzes smaller sub-portions, and normal laws hold. Just a caution before extending experience between the two. -- Kuuran


Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited April 8, 2008 19:55 EST by Rednaxela (diff)
Search: