How do I display a full 360 degrees using Actionscript 2 and Trigonometry? - actionscript-2

I'm creating a game that uses trigonometry to calculate and display distance and degrees in dynamic text boxes. I'm calculating the distance of my cursor from center of a movie clip. And using that center of the movie clip, I'm trying to calculate and display a full 360º as my cursor moves around the swf. I have the distance part of the game working but the part that displays degrees is not working properly. The dynamic text box only display from 90º thru 270º. Instead of going past 270º to 360º/0º to 90º, it just counts back down from 270º to 90º. Below is my actionscript. I'd greatly appreciate any help or suggestions. Thanks!
//Mouse and Dynamic Text Boxes-------------------------
Mouse.hide();
onMouseMove = function () {
feedback.text = "You are moving your mouse";
cursor._x = _xmouse;
cursor._y = _ymouse;
updateAfterEvent();
xmouse_value.text = Math.atan2((a), (b));
ymouse_value.text = Math.round(radians*180/Math.PI)
updateAfterEvent();
};
Mouse.addListener(myListener);
//distance (RANGE)
_root.onEnterFrame = function () {
xmid = Stage.width/2;
ymid = Stage.height/2;
a = _root._ymouse-ymid;
b = _root._xmouse-xmid;
c = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2));
feedbacka.text = Math.round(a);
feedbackb.text = Math.round(b);
feedbackc.text = Math.round(c/30.4);
updateAfterEvent();
var radians:Number;
var degrees:Number;
//Calculcate Radians
//Radians specify an angle by measuring the length around the path of the circle.
radians = Math.atan2((c), (b))
//calculate degrees
//the angle the circle is in relation to the center point
//update text box inside circle
radians_txt = Math.round(radians*360/Math.PI);
degrees_txt = Math.round(radians*180/Math.PI);
updateAfterEvent();
//getting past 270 degrees
radians2_txt = Math.round(radians/Math.PI);
radians2_txt = Math.floor(radians + -270);
}

The parameters to atan2 should be the delta-y and delta-x between the two points, but you are passing the distance between the two points and the delta-x. Try this instead:
radians = Math.atan2(a, b);
The next problem is to convert the radians into degrees. To convert radians to degrees, you can do this:
degrees_txt = radians * 180 / Math.PI;
Note that atan2 returns from between -Math.PI / 2 to Math.PI / 2. When converted to degrees, this range becomes -180 to 180. To convert to 0 to 360, you can add 360 to the result if it is negative:
if(degrees_txt < 0) degrees_txt += 360;

Related

How to teleport a player two block on his left?

I tried several things, like using vectors, but It didn't work for me. Than I tried searching on the internet and it didn't work as well.
Vector direc = l.getDirection().normalize();
direc.setY(l.getY());
direc.normalize();
direc.multiply(-1);
l.add(direc);
Player#teleport(l.getBlock().getLocation());
// or
Player#teleport(l);
Use Vector#rotateAroundY​ to rotate the player's direction vector 90 degrees to the left.
Vector dir = player.getLocation().getDirection(); // get player's direction vector
dir.setY(0).normalize(); // get rid of the y component
dir.rotateAroundY(Math.PI / 2); // rotate it 90 degrees to the left
dir.multiply(2); // make the vector's length 2
Location newLocation = player.getLocation().add(dir); // add the vector to the player's location to get the new location
Location location = player.getLocation();
Vector direction = location.getDirection();
direction.normalize();
float newZ = (float)(location.getZ() + (2 * Math.sin(Math.toRadians(location.getYaw() + 90 * direction)))); //2 is your block amount in Z direction
float newX = (float)(location.getX() + (Math.cos(Math.toRadians(location.getYaw() + 90 * direction))));
You have to know in which direction you want to teleport the player

CCMoveTo duration / speed issue

Some help would be most appreciated. Sprite movement based upon a heading that is given from a touch on the screen. Sprite moves as expected but I am unable to vary the speed, no matter what value I use for currentSpeed. This is in the update method of the sprite. Thanks in advance.
// Distance between two points (Distance formula, Pythagorean Theorem c^2=a^2+b^2, so d=sqrt((x2-x1)^2+(y2-y1)^2)
// Duration (time = distance / rate)
CGPoint adjustedPosition;
adjustedPosition.x = position_.x - sinf(heading);
adjustedPosition.y = position_.y - cosf(heading);
float distance = CGPointDistanceBetweenTwoPoints(adjustedPosition, position_);
float duration = distance / currentSpeed;
position_ = adjustedPosition;
[self runAction:[CCMoveTo actionWithDuration:duration position:position_]];
dont use a moveto or for that matter any action in an update method. Instead, compute the position , something like this:
-(void) update:(ccTime) dt {
// _velocity in points per second.
// heading should be in ccw notation, 0 on x axis, RHS
float deltaX = dt * _velocity * cosf(heading);
float deltaY = dt * _velocity * sinf(heading);
CGPoint adjustedPosition = ccpAdd(self.position, ccp(deltaX,deltaY));
self.position = adjustedPosition;
}
or something similar. This will ease out any variance id dt, for which the only thing you can bet on is that it wont be constant ; but the physics should be right.
Try this for distance:
float distance = ccpLength(ccpSub(adjustedPosition, position_));

NSPoint offset by pixels toward angle?

Let me just start with the code.
- (NSPoint*) pointFromPoint:(NSPoint*)point withDistance:(float)distance towardAngle:(float)angle; {
float newX = distance * cos(angle);
float newY = distance * sin(angle);
NSPoint * anNSPoint;
anNSPoint.x = newX;
anNSPoint.y = newY;
return thePoint;
}
This should, based on my knowledge, be perfect. It should return and x value of 0 and a y value of 2 if I call this code.
somePoint = [NSPoint pointFromPoint:somePoint withDistance:2 towardAngle:90];
Instead, I get and x value of 1.05 and a y of 1.70. How can I find the x and y coordinates based on an angle and a distance?
Additional note: I have looked on math.stackexchange.com, but the formulas there led me to this. I need the code, not the normal math because I know I will probably screw this up.
A working version of your function, which accepts values in degrees instead of radians, would look like this:
- (NSPoint)pointFromPoint:(NSPoint)origin withDistance:(float)distance towardAngle:(float)angle
{
double radAngle = angle * M_PI / 180.0;
return NSMakePoint(origin.x + distance * cos(radAngle), point.y + distance * sin(radAngle));
}
Your problem is you're giving the angle in degrees (e.g. 90), but the math is expecting it in radians. Try replacing the 90 with M_PI_2

Map GPS Coordinates to an Image and draw some GPS Points on it

I have some problems figuring out where my error is. I got the following:
Have an image and corresponding GPS coordinates of its top-left and bottom-right vertices.
E.g:
topLeft.longitude = 8.235128;
topLeft.latitude = 49.632383;
bottomRight.longitude = 8.240547;
bottomRight.latitude = 49.629808;
Now a have an Point that lies in that map:
p.longitude = 8.238567;
p.latitude = 49.630664;
I draw my image in landscape fullscreen (1024*748).
Now I want to calculate the exact Pixel position (x,y) of my point.
For doing that I am trying to use the great circle distance approach from here: Link.
CGFloat DegreesToRadians(CGFloat degrees)
{
return degrees * M_PI / 180;
};
- (float) calculateDistanceP1:(CLLocationCoordinate2D)p1 andP2:(CLLocationCoordinate2D)p2 {
double circumference = 40000.0; // Erdumfang in km am Äquator
double distance = 0.0;
double latitude1Rad = DegreesToRadians(p1.latitude);
double longitude1Rad = DegreesToRadians(p1.longitude);
double latititude2Rad = DegreesToRadians(p2.latitude);
double longitude2Rad = DegreesToRadians(p2.longitude);
double logitudeDiff = fabs(longitude1Rad - longitude2Rad);
if (logitudeDiff > M_PI)
{
logitudeDiff = 2.0 * M_PI - logitudeDiff;
}
double angleCalculation =
acos(sin(latititude2Rad) * sin(latitude1Rad) + cos(latititude2Rad) * cos(latitude1Rad) * cos(logitudeDiff));
distance = circumference * angleCalculation / (2.0 * M_PI);
NSLog(#"%f",distance);
return distance;
}
Here is my code for getting the Pixel position:
- (CGPoint) calculatePoint:(CLLocationCoordinate2D)point {
float x_coord;
float y_coord;
CLLocationCoordinate2D x1;
CLLocationCoordinate2D x2;
x1.longitude = p.longitude;
x1.latitude = topLeft.latitude;
x2.longitude = p.longitude;
x2.latitude = bottomRight.latitude;
CLLocationCoordinate2D y1;
CLLocationCoordinate2D y2;
y1.longitude = topLeft.longitude;
y1.latitude = p.latitude;
y2.longitude = bottomRight.longitude;
y2.latitude = p.latitude;
float distanceX = [self calculateDistanceP1:x1 andP2:x2];
float distanceY = [self calculateDistanceP1:y1 andP2:y2];
float distancePX = [self calculateDistanceP1:x1 andP2:p];
float distancePY = [self calculateDistanceP1:y1 andP2:p];
x_coord = fabs(distancePX * (1024 / distanceX))-1;
y_coord = fabs(distancePY * (748 / distanceY))-1;
return CGPointMake(x_coord,y_coord);
}
x1 and x2 are the points on the longitude of p and with latitude of topLeft and bottomRight.
y1 and y2 are the points on the latitude of p and with longitude of topLeft and bottomRight.
So I got the distance between left and right on longitude of p and distance between top and bottom on latitude of p. (Needed for calculate the pixel position)
Now I calculate the distance between x1 and p (my distance between x_0 and x_p) after that I calculate the distance between y1 and p (distance between y_0 and y_p)
Last but not least the Pixel position is calculated and returned.
The Result is, that my point is on the red and NOT on the blue position:
Maybe you find any mistakes or have any suggestions for improving the accuracy.
Maybe I didn't understand your question, but shouldn't you be using the Converting Map Coordinates methods of MKMapView?
See this image
I used your co-ordinates, and simply did the following:
x_coord = 1024 * (p.longitude - topLeft.longitude)/(bottomRight.longitude - topLeft.longitude);
y_coord = 748 - (748 * (p.latitude - bottomRight.latitude)/(topLeft.latitude - bottomRight.latitude));
The red dot markes this point. For such small distances you don't really need to use great circles, and your rounding errors will be making things much more inaccurate

calculate latitude and longitude along a circumference of a known circle with known distance

I dont need help with a programming language, I need help from someone to calculate the gps coordinates of points of a specific distance, namely 22 feet apart, on the circumference of a circle. I know the beginning gps coordinates and the radius. I am pretty sure the haversine, or the speherical law of cosines has the answer, but its been a long time since I have used any trig formulas and I cant figure it out. I am using decimal degrees and am programing in this vb.net. If someone could dumb this down for me it would be a great help.
As I understand you have:
Coordinate of the center of
circumference.
Distance between
two point on the circumference of a
circle.
Radius of circumference.
In my opinion this is not enough for calculating other point's coordinates. You should have as minimum yet one point coordinate, because we only can guess where points are placed on the circumference.
Here's the basic algorithm:
Calculate the angular measure whose arc length is 22 feet, with the given radius
numPoints = Math.PI * 2 / angularMeasure
for i in range(numPoints):
calculate proportion around the circle we are, in terms of degrees or radians
calculate the location of the endpoint of a great circle or rhumb arc from the center point moving in the specific azimuth direction (from the proportion around the circle) the given radius
This last point is the hardest part. Here's code from the WorldWind SDK (available: http://worldwind.arc.nasa.gov/java/) (Note- you'll have to calculate the radius in terms of angles, which you can do pretty easily given the radius / circumference of the earth)
/*
Copyright (C) 2001, 2006 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
/**
* Computes the location on a rhumb line with the given starting location, rhumb azimuth, and arc distance along the
* line.
*
* #param p LatLon of the starting location
* #param rhumbAzimuth rhumb azimuth angle (clockwise from North)
* #param pathLength arc distance to travel
*
* #return LatLon location on the rhumb line.
*/
public static LatLon rhumbEndPosition(LatLon p, Angle rhumbAzimuth, Angle pathLength)
{
if (p == null)
{
String message = Logging.getMessage("nullValue.LatLonIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (rhumbAzimuth == null || pathLength == null)
{
String message = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
double lat1 = p.getLatitude().radians;
double lon1 = p.getLongitude().radians;
double azimuth = rhumbAzimuth.radians;
double distance = pathLength.radians;
if (distance == 0)
return p;
// Taken from http://www.movable-type.co.uk/scripts/latlong.html
double lat2 = lat1 + distance * Math.cos(azimuth);
double dPhi = Math.log(Math.tan(lat2 / 2.0 + Math.PI / 4.0) / Math.tan(lat1 / 2.0 + Math.PI / 4.0));
double q = (lat2 - lat1) / dPhi;
if (Double.isNaN(dPhi) || Double.isNaN(q) || Double.isInfinite(q))
{
q = Math.cos(lat1);
}
double dLon = distance * Math.sin(azimuth) / q;
// Handle latitude passing over either pole.
if (Math.abs(lat2) > Math.PI / 2.0)
{
lat2 = lat2 > 0 ? Math.PI - lat2 : -Math.PI - lat2;
}
double lon2 = (lon1 + dLon + Math.PI) % (2 * Math.PI) - Math.PI;
if (Double.isNaN(lat2) || Double.isNaN(lon2))
return p;
return new LatLon(
Angle.fromRadians(lat2).normalizedLatitude(),
Angle.fromRadians(lon2).normalizedLongitude());
}
You are looking for the equation of what is called a "small circle". Look at this book for the equation of the small circle and the arc length equation for that small circle. However, because your distances are so small, you could consider your area flat and use simpler geometry. Using UTM coordinates would make the calculations much simpler than using lat/long.
The Haversine formula relates to great circles, not small circles...