In this, what is "a"? How to explain it?
s=regionprops(L,'Perimeter','Area');
a=s.Perimeter^2/s.Area;
%use one letter for simplicity, returns the value for perimeter and area
% for square ((a>17) && (a<20))
%for circle ((a>13) && (a<17))
% for triangle ((a>20) && (a<30))
The value of a is a measure of the roundness or circularity of the shape L. The minimum is achieved for circles:
s.Area = pi * r^2
s.Perimeter = 2 * pi * r
a = 4 * pi = 12.566...
Other shapes will always have greater values. For instance, for squares:
s.Area = l^2
s.Perimeter = 4 * l
a = 16
or for equilateral triangles:
s.Area = sqrt(3) * l^2 / 4
s.Perimeter = 3 * l
a = 12 * sqrt(3) = 20.78...
I'm building a gauge. I took off from an example that was a half circle, see from the image:
To transform percentage into the angle the original chart had these three functions:
percToDeg: function (perc) {
return perc * 360;
},
percToRad: function (perc) {
return this.degToRad(this.percToDeg(perc));
},
degToRad: function (deg) {
return deg * Math.PI / 180;
},
Now this all looks and works great, however I wanted to adjust the gauge so that the arc extends another 45 degrees in both directions, see this:
However now percToDeg function doesn't work anymore. Can you please help me figure out a function that for a given percentage places the point (tip of the needle in my case) of on the arc correctly - 0% should be 225 degrees, 50% 90 degrees and 100% -45 degrees?
Thanks
You want to use something called linear interpolation, with your starting range being [0, 100] and your destination range being [225, -45].
The general equation for this, for an x in range [a, b] to y in range [c, d]
y = c + (x - a) * (d - c) / (b - a)
In your case,
a = 0
b = 100
c = 225
d = -45
For example, if you want to find where 50 maps to in the range:
y = 225 + (50 - 0) * (-45 - 225) / (100 - 0)
y = 225 + 50 * -270 / 100
y = 225 - 135
y = 90
Good whatever time of day! I have some sprite:
A point has coordinates Actor.x; Actor.y.
AB length = 96
BC length = 86
AC length = 42
All calculations are approximate, I made it with help the ruler in Photoshop.
Sprite always towards mouse, angle (in radians) stores in Actor.direction variable. I draw sprite with scale 0.3.
All bullets toward mouse (that is Bullet.direction == Actor.direction). I need to create bullets in the B point. How I can calculate coordinates of the B point with any angle?
UPD
If I will create bullets in the coordinates:
x = Actor.x + 96 * math.cos(Actor.direction) * 0.3
y = Actor.y + 96 * math.sin(Actor.direction) * 0.3
I get it:
Excuse my bad English! It isn't my native language. Thank you in advance!
Let
cs = math.cos(Actor.direction)
sn = math.sin(Actor.direction)
point B will be shifted from A by
dx = - 42 * sn + 86 * cs
dy = 42 * cs + 86 * sn
Perhaps you will need to change signs before both 42s
(I did not account for scale)
using a Latitude and Longitude value (Point A), I am trying to calculate another Point B, X meters away bearing 0 radians from point A. Then display the point B Latitude and Longitude values.
Example (Pseudo code):
PointA_Lat = x.xxxx;
PointA_Lng = x.xxxx;
Distance = 3; //Meters
bearing = 0; //radians
new_PointB = PointA-Distance;
I was able to calculate the distance between two Points but what I want to find is the second point knowing the distance and bearing.
Preferably in PHP or Javascript.
Thank you
It seems you are measuring distance (R) in meters, and bearing (theta) counterclockwise from due east. And for your purposes (hundereds of meters), plane geometry should be accurate enough. In that case,
dx = R*cos(theta) ; theta measured counterclockwise from due east
dy = R*sin(theta) ; dx, dy same units as R
If theta is measured clockwise from due north (for example, compass bearings),
the calculation for dx and dy is slightly different:
dx = R*sin(theta) ; theta measured clockwise from due north
dy = R*cos(theta) ; dx, dy same units as R
In either case, the change in degrees longitude and latitude is:
delta_longitude = dx/(111320*cos(latitude)) ; dx, dy in meters
delta_latitude = dy/110540 ; result in degrees long/lat
The difference between the constants 110540 and 111320 is due to the earth's oblateness
(polar and equatorial circumferences are different).
Here's a worked example, using the parameters from a later question of yours:
Given a start location at longitude -87.62788 degrees, latitude 41.88592 degrees,
find the coordinates of the point 500 meters northwest from the start location.
If we're measuring angles counterclockwise from due east, "northwest" corresponds
to theta=135 degrees. R is 500 meters.
dx = R*cos(theta)
= 500 * cos(135 deg)
= -353.55 meters
dy = R*sin(theta)
= 500 * sin(135 deg)
= +353.55 meters
delta_longitude = dx/(111320*cos(latitude))
= -353.55/(111320*cos(41.88592 deg))
= -.004266 deg (approx -15.36 arcsec)
delta_latitude = dy/110540
= 353.55/110540
= .003198 deg (approx 11.51 arcsec)
Final longitude = start_longitude + delta_longitude
= -87.62788 - .004266
= -87.632146
Final latitude = start_latitude + delta_latitude
= 41.88592 + .003198
= 41.889118
It might help if you knew that 3600 seconds of arc is 1 degree (lat. or long.), that there are 1852 meters in a nautical mile, and a nautical mile is 1 second of arc. Of course you're depending on the distances being relatively short, otherwise you'd have to use spherical trigonometry.
Here is an updated version using Swift:
let location = CLLocation(latitude: 41.88592 as CLLocationDegrees, longitude: -87.62788 as CLLocationDegrees)
let distanceInMeter : Int = 500
let directionInDegrees : Int = 135
let lat = location.coordinate.latitude
let long = location.coordinate.longitude
let radDirection : CGFloat = Double(directionInDegrees).degreesToRadians
let dx = Double(distanceInMeter) * cos(Double(radDirection))
let dy = Double(distanceInMeter) * sin(Double(radDirection))
let radLat : CGFloat = Double(lat).degreesToRadians
let deltaLongitude = dx/(111320 * Double(cos(radLat)))
let deltaLatitude = dy/110540
let endLat = lat + deltaLatitude
let endLong = long + deltaLongitude
Using this extension:
extension Double {
var degreesToRadians : CGFloat {
return CGFloat(self) * CGFloat(M_PI) / 180.0
}
}
dx = sin(bearing)
dy = cos(bearing)
x = center.x + distdx;
y = center.y + distdy;
atan2(y, x) has that discontinuity at 180° where it switches to -180°..0° going clockwise.
How do I map the range of values to 0°..360°?
here is my code:
CGSize deltaPoint = CGSizeMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
float swipeBearing = atan2f(deltaPoint.height, deltaPoint.width);
I'm calculating the direction of a swiping touch event given the startPoint and endPoint, both XY point structs. The code is for the iPhone but any language that supports atan2f() will do.
Solution using Modulo
A simple solution that catches all cases.
degrees = (degrees + 360) % 360; // +360 for implementations where mod returns negative numbers
Explanation
Positive: 1 to 180
If you mod any positive number between 1 and 180 by 360, you will get the exact same number you put in. Mod here just ensures these positive numbers are returned as the same value.
Negative: -180 to -1
Using mod here will return values in the range of 180 and 359 degrees.
Special cases: 0 and 360
Using mod means that 0 is returned, making this a safe 0-359 degrees solution.
(x > 0 ? x : (2*PI + x)) * 360 / (2*PI)
Add 360° if the answer from atan2 is less than 0°.
Or if you don't like branching, negate the two parameters and add 180° to the answer.
(Adding 180° to the return value puts it nicely in the 0-360 range, but flips the angle. Negating both input parameters flips it back.)
#erikkallen is close but not quite right.
theta_rad = atan2(y,x);
theta_deg = (theta_rad/M_PI*180) + (theta_rad > 0 ? 0 : 360);
This should work in C++: (depending on how fmod is implemented, it may be faster or slower than the conditional expression)
theta_deg = fmod(atan2(y,x)/M_PI*180,360);
Alternatively you could do this:
theta_deg = atan2(-y,-x)/M_PI*180 + 180;
since (x,y) and (-x,-y) differ in angles by 180 degrees.
I have 2 solutions that seem to work for all combinations of positive and negative x and y.
1) Abuse atan2()
According to the docs atan2 takes parameters y and x in that order. However if you reverse them you can do the following:
double radians = std::atan2(x, y);
double degrees = radians * 180 / M_PI;
if (radians < 0)
{
degrees += 360;
}
2) Use atan2() correctly and convert afterwards
double degrees = std::atan2(y, x) * 180 / M_PI;
if (degrees > 90)
{
degrees = 450 - degrees;
}
else
{
degrees = 90 - degrees;
}
#Jason S: your "fmod" variant will not work on a standards-compliant implementation. The C standard is explicit and clear (7.12.10.1, "the fmod functions"):
if y is nonzero, the result has the same sign as x
thus,
fmod(atan2(y,x)/M_PI*180,360)
is actually just a verbose rewriting of:
atan2(y,x)/M_PI*180
Your third suggestion, however, is spot on.
Here's some javascript. Just input x and y values.
var angle = (Math.atan2(x,y) * (180/Math.PI) + 360) % 360;
This is what I normally do:
float rads = atan2(y, x);
if (y < 0) rads = M_PI*2.f + rads;
float degrees = rads*180.f/M_PI;
An alternative solution is to use the mod () function defined as:
function mod(a, b) {return a - Math.floor (a / b) * b;}
Then, with the following function, the angle between ini(x,y) and end(x,y) points is obtained. The angle is expressed in degrees normalized to [0, 360] deg. and North referencing 360 deg.
function angleInDegrees(ini, end) {
var radian = Math.atan2((end.y - ini.y), (end.x - ini.x));//radian [-PI,PI]
return mod(radian * 180 / Math.PI + 90, 360);
}
angle = Math.atan2(x,y)*180/Math.PI;
I have made a Formula for orienting angle into 0 to 360
angle + Math.ceil( -angle / 360 ) * 360;
double degree = fmodf((atan2(x, y) * (180.0 / M_PI)) + 360, 360);
This will return degree from 0°-360° counter-clockwise, 0° is at 3 o'clock.
A formula to have the range of values from 0 to 360 degrees.
f(x,y)=180-90*(1+sign(x))* (1-sign(y^2))-45*(2+sign(x))*sign(y)
-(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
The R packages geosphere will calculate bearingRhumb, which is a constant bearing line given an origin point and easting/northing. The easting and northing must be in a matrix or vector. The origin point for a wind rose is 0,0. The following code seems to readily resolve the issue:
windE<-wind$uasE
windN<-wind$vasN
wind_matrix<-cbind(windE, windN)
wind$wind_dir<-bearingRhumb(c(0,0), wind_matrix)
wind$wind_dir<-round(wind$wind_dir, 0)
theta_rad = Math.Atan2(y,x);
if(theta_rad < 0)
theta_rad = theta_rad + 2 * Math.PI; //if neg., add 2 PI to it
theta_deg = (theta_rad/M_PI*180) ; //convert from radian to degree
//or
theta_rad = Math.Atan2(y,x);
theta_rad = (theta_rad < 0) ? theta_rad + 2 * Math.PI : theta_rad;
theta_deg = (theta_rad/M_PI*180) ;
-1 deg becomes (-1 + 360) = 359 deg
-179 deg becomes (-179 + 360) = 181 deg
For your application I suspect you don't need exact degrees and would prefer a more approximate compass angle, eg 1 of 16 directions? If so then this code avoids atan issues and indeed avoids floating point altogether. It was written for a video game so uses 8 bit and 16 bit integers:
/*
349.75d 11.25d, tan=0.2034523
\ /
\ Sector /
\ 0 / 22.5d tan = ?2 - 1
15 | 1 33.75
| / 45d, tan = 1
14 | 2 _56.25
| / 67.5d, tan = 1 + ?2
13 | 3
| __ 78.75
|
12---------------+----------------4 90d tan = infty
| __ 101.25
|
11 | 5
|
10 | 6
|
9 | 7
8
*/
// use signs to map sectors:
static const int8_t map[4][5] = { /* +n means n >= 0, -n means n < 0 */
/* 0: +x +y */ {0, 1, 2, 3, 4},
/* 1: +x -y */ {8, 7, 6, 5, 4},
/* 2: -x +y */ {0, 15, 14, 13, 12},
/* 3: -x -y */ {8, 9, 10, 11, 12}
};
int8_t sector(int8_t x, int8_t y) { // x,y signed in range -128:127, result 0:15 from north, clockwise.
int16_t tangent; // 16 bits
int8_t quadrant = 0;
if (x > 0) x = -x; else quadrant |= 2; // make both negative avoids issue with negating -128
if (y > 0) y = -y; else quadrant |= 1;
if (y != 0) {
// The primary cost of this algorithm is five 16-bit multiplies.
tangent = (int16_t)x*32; // worst case y = 1, tangent = 255*32 so fits in 2 bytes.
/*
determine base sector using abs(x)/abs(y).
in segment:
0 if 0 <= x/y < tan 11.25 -- centered around 0 N
1 if tan 11.25 <= x/y < tan 33.75 -- 22.5 NxNE
2 if tan 33.75 <= x/y < tan 56.25 -- 45 NE
3 if tan 56.25 <= x/y < tan 78.75 -- 67.5 ExNE
4 if tan 78.75 <= x/y < tan 90 -- 90 E
*/
if (tangent > y*6 ) return map[quadrant][0]; // tan(11.25)*32
if (tangent > y*21 ) return map[quadrant][1]; // tan(33.75)*32
if (tangent > y*47 ) return map[quadrant][2]; // tan(56.25)*32
if (tangent > y*160) return map[quadrant][3]; // tan(78.75)*32
// last case is the potentially infinite tan(90) but we don't need to check that limit.
}
return map[quadrant][4];
}