Difference between revisions of "Getting started with angles"
| Line 10: | Line 10: | ||
To get the other robot's Absolute Bearing to you, add Math.PI (180 degrees). To get the perpendicular angle so you can orbit them, add Math.PI/2 (90 degrees). [[NanoBots]] typically orbit with Math.cos(e.getBearingRadians()) instead. | To get the other robot's Absolute Bearing to you, add Math.PI (180 degrees). To get the perpendicular angle so you can orbit them, add Math.PI/2 (90 degrees). [[NanoBots]] typically orbit with Math.cos(e.getBearingRadians()) instead. | ||
| − | To calculate the Absolute Bearing from | + | To calculate the Absolute Bearing from a source location to another location, you can use a method like the following from [[GFTargetingBot]]: |
| − | absoluteBearing | + | static double absoluteBearing(Point2D source, Point2D target) { |
| + | return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY()); | ||
| + | } | ||
== Moving to an angle == | == Moving to an angle == | ||
Latest revision as of 21:57, 16 January 2026
Angles are important for Radar, Movement, and Targeting. Some trigonometric methods measure angles in radians, but Robocode has different methods for both radians and degrees.
Contents
Absolute Bearing
Absolute Bearing is the absolute angle from one robot to another robot. You can calculate the Absolute Bearing from your robot in onScannedRobot as
absoluteBearing = e.getBearingRadians() + getHeadingRadians();
The robot's heading is an absolute angle (0 to 360 degrees), and the bearing to the scanned robot is a relative angle (-180 to 180 degrees).
To get the other robot's Absolute Bearing to you, add Math.PI (180 degrees). To get the perpendicular angle so you can orbit them, add Math.PI/2 (90 degrees). NanoBots typically orbit with Math.cos(e.getBearingRadians()) instead.
To calculate the Absolute Bearing from a source location to another location, you can use a method like the following from GFTargetingBot:
static double absoluteBearing(Point2D source, Point2D target) {
return Math.atan2(target.getX() - source.getX(), target.getY() - source.getY());
}
Moving to an angle
The easiest way to move your robot at a certain angle is the following:
angle = targetAngle - getHeadingRadians(); setAhead(Math.cos(angle) * bigNumber); setTurnRightRadians(Math.tan(angle));
An alternative to slowly turning your robot with Utils.normalRelativeAngle, this technique reverses movement direction when the robot needs to make a very large turn.
Utils.normalRelativeAngle
Large turns in one direction take a lot more time than small turns in the opposite direction, so doing simple arithmetic with angles can cause problems. Luckily, Robocode provides a method to normalize relative angles. This is used very often in targeting to get the gun turn amount:
setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing + targetingOffset - getGunHeadingRadians()));
Utils.normalAbsoluteAngle
This method normalizes absolute angles. It is useful when counting data about all angles around the robot. Cotillion uses it for Multiple Choice Pattern Matching.
Comparing angles
To calculate how far one angle is from another, you can use Math.abs(Utils.normalRelativeAngle(absoluteAngleA - absoluteAngleB)).
Relative bins
For Visit Count Stats with relative angles, you need to have a total number of bins and a middle factor index (for the Absolute Bearing). To convert a relative angle to a bin index, you can normalize the angle to 0-1, multiply by the number of bins and round, then add the middle factor. In Guess Factor Targeting, the maximum angle is the Maximum Escape Angle.
statistics[index = ((int)Math.round((angle / maxAngle) * BINS) + MIDDLE)]++;
To convert an index into an angle, simply invert:
angle = (index - MIDDLE) * maxAngle / BINS;
Absolute bins
Absolute bins don't need a middle factor index, and the maximum angle is a full circle (Math.PI*2 or 360 degrees).
statistics[index = ((int)Math.round((angle / Math.PI*2) * BINS))]++; angle = index * Math.PI*2 / BINS;
Projecting a location
To obtain a new location at a certain distance and angle from a source location, you can use a method like the following from GFTargetingBot:
static Point2D project(Point2D sourceLocation, double angle, double length) {
return new Point2D.Double(sourceLocation.getX() + Math.sin(angle) * length, sourceLocation.getY() + Math.cos(angle) * length);
}