I have two coordinates that I want to convert to UTM and DMS, but I cant figure out which format they are in.
The coortinates: N7833 E01418
Does anyone know or are they bogus?
The coordinates where in degrees and minutes.
N7833 = Hemisphere N, Degrees 78, Minutes 33
N01418 = Hemisphere N, Degrees 014, Minutes 18
Related
I would like to make a rotation using 4x4 matrix in Swift, but it has unexpected behavior: 200 degrees + 45 degrees = 115 degrees, and not 245
let degree200 = Angle(degrees: 200).radians
let degree45 = Angle(degrees: 45).radians
// 200 degrees + 45 degrees
let rotationMatrix = float4x4(simd_quatf(angle: Float(degree200+degree45), axis: SIMD3<Float>(0, 1, 0)))
// it prints 115 degree, and not 245
print(Angle(radians: Double(simd_quatf(rotationMatrix).angle)).degrees)
I assume that's a typo, and you in fact meant -115 degrees? (remainder(245, 360)) When using quaternions & Matrices to express orientations, you can only expect to see values of -180 to +180 degrees when converting those values back to Euler angles.
In general it is impossible to convert back to Euler angles from either a quaternion or matrix and get the original input values back. You either store the original Euler angles and present those to the user, or you will have to have a known starting Euler value and apply an Euler filter to obtain approximately correct results.
The only correct way to get your expected result is to NOT print the value after conversion to quats:
print((degree200 + degree45). degrees)
Well I know 115 and 245 are 360. Just a guess but maybe you're rotating the wrong way?? Maybe try negative values and see what happens.
I'm having trouble understanding what precisely the output of meshgrat means and how this relates to the lat and lon parameters of pcolorm(lat,lon,Z). I have a grid of global data, I'll call Z, at a 1.5 degree latitude x 1.5 degree longitude spatial resolution. Thus I have a matrix that's 120 x 240 (180 degrees of latitude / 1.5 = 120, 360 degrees of longitude / 1.5 = 240). Row 1 is 90 N and column 1 is 180 W (-180).
If I follow the MATLAB documentation, I can use meshgrat to produce the lat and lon arguments that I need to supply to pcolorm as follows.
latlim = [-90 90];
lonlim = [-180 180];
[lat,lon] = meshgrat(latlim,lonlim,[120 240]);
However, I don't understand why the spacing of the output is the way it is. For example, the first five values of lat are [-90.0000, -88.4874, -86.9748,-85.4622,-83.9496...]. The lon values follow the same spacing. The spacing is very close to 1.5 degrees, but it isn't. Why is there a discrepancy? The documentation claims that the paired lat and lon values are the location of the graticule vertices. In that case, these values make some sense, since there will always be one more vertex than actual grid cells. To test this, I made the following adjustment to the meshgrat code by adding one extra row and column:
latlim2 = [-90 90];
lonlim2 = [-180 180];
[lat2,lon2] = meshgrat(latlim2,lonlim2,[121 241]);
This did, indeed, produce the expected output, with the spacing now exactly at 1.5 degrees (i.e [-90.0000, -88.5000, -87.0000, -85.5000, -84.0000...]). Again, this is logical if these are viewed as vertices. But under this scenario lat and lon no longer match Z in size, which goes against how the documentation says to treat lat and lon in this case.
There seems to be a mismatch here: either the spacing in the lat lon grids are not accurate, or the girds are not the same size as the data, which would be fine in my mind as long as MATLAB knows how to interpret them accordingly, but the documentation does not seem to suggest using it this way. I have no detailed knowledge of how the MATLAB functions work at a finer level. Can someone explain to me what I'm missing?
Thus I have a matrix that's 120 x 240 (180 degrees of latitude / 1.5 = 120, 360 degrees of longitude / 1.5 = 240).
180/1.5 is indeed 120. But you also have an element at 0deg (presumably). That's 121.
I have some questions about converting kilometers to geographical coordinates.
As you can see figure attached, the left one is trajectory interms of kilometers. I entered geographical coordinates and calculate trajectory as kilometers. For my calculations I need to convert degrees to kilometers. I used this code:
LAT=[41.030503; 41.048334; 41.071551 ]*pi/180;
LON=[28.999000; 29.037494; 29.052138 ]*pi/180;
for i=1:length(LAT)-1
psi_coordinate(i,1) = atan2( sin (LON(i+1)-LON(i)) * cos (LAT(i+1)) , cos (LAT(i)) *sin (LAT(i+1)) - sin (LAT(i)) * cos (LAT(i+1)) * cos (LON(i+1)-LON(i)) );
a=(sin((LAT(i+1)-LAT(i))/2))^2+cos(LAT(i))*cos(LAT(i+1))*(sin((LON(i+1)-LON(i))/2))^2;
c=2*atan2(sqrt(a),sqrt(1-a));
d(i,1)=R*c;
pos_x(i+1,1)=pos_x(i,1)+d(i,1)*cos(psi_coordinate(i,1)); %convert to kilometer
pos_y(i+1,1)=pos_y(i,1)+d(i,1)*sin(psi_coordinate(i,1)); %convert to kilometer
distance_h(i,1)=sqrt(((LAT(i+1)-LAT(i))^2)+((LON(i+1)-LON(i))^2))*1000 ; %kilometer
end
distance=sum(d);
pos_x=pos_x*1000; %convert to meter
pos_y=pos_y*1000; %convert to meter
pos_x and pos_y are ploted as circle at the figure (left).
After I calculate ship trajectory, I need to convert them degrees again.
If I use "km2deg" command I obtained my coordinates as given figure (right) and the code that I used is:
ydeg=LON(1)*180/pi+km2deg(y/1000);
xdeg=LAT(1)*180/pi+km2deg(x/1000);
But as you can see the blue line (ship trajectory) is not close to the desired path as figure given left. Normally it should be the same trend for these two plot. Because all I do is here is just converting the units. I guess I have some troubles to used "km2deg" command.
Do you have any suggestions to convert my points correctly from km to deg?
For projection I am using
m_proj('Mercator')
Next I use the following to convert an array of lon and lat points into x y coordinates.
[x,y] = m_ll2xy(lon,lat)
The [x,y] I got were in some units that I didn't understand. For example the x corresponding to longitude of -180 and 180 degrees are -pi and pi, while the y corresponding to latitude of -85 to 85 degrees are -3.1313 and 3.1313.
I want to get the [x,y] in units of km, which I understand have to be defined from a fixed point. How can I do this? Thanks
There are two views:
viewA and viewB. Both are rotated.
The coordinate system for rotation is weird: It goes from 0 to 179,999999 or -179,99999 degrees. So essentially 179,99999 and -179,99999 are very close together!
I want to calculate how much degrees or radians are between these rotations.
For example:
viewA is rotated at 20 degrees
viewB is rotated at 30 degrees
I could just do: rotationB - rotationA = 10.
But the problem with this formula:
viewA is rotated at 179 degrees
viewB is rotated at -179 degrees
that would go wrong: rotationB - rotationA = -179 - 179 = -358
358 is plain wrong, because they are very close together in reality. So one thing I could do maybe is to check if the absolute result value is bigger than 180, and if so, calculate it the other way around to get the short true delta. But I feel this is plain wrong and bad, because of possible floating point errors and unprecision. So if two views are rotated essentially equally at 179,99999999999 degrees I might get a weird 180 or a 0 if I am lucky.
Maybe there's a genius-style math formular with PI, sine or other useful stuff to get around this problem?
EDIT: Original answer (with Mod) was wrong. would have given 180 - right answer in certain circumstances (angles 30 and -20 for example would give answer of 130, not correct answer of 50):
Two correct answers for all scenarios:
If A1 and A2 are two angles (between -179.99999 and 179.99999,
and Abs means take the Absolute Value,
The angular distance between them, is expressed by:
Angle between = 180 - Abs(Abs(A1 - A2) - 180)
Or, using C-style ternary operator:
Angle between = A1 < 180 + A2? A1 - A2: 360 + A1 - A2
Judging from the recent questions you've asked, you might want to read up on the unit circle. This is a fundamental concept in trigonometry, and it is how angles are calculated when doing rotations using CGAffineTransforms or CATransform3Ds.
Basically, the unit circle goes from 0 to 360 degrees, or 0 to 2 * pi (M_PI is the constant used on the iPhone) radians. Any angle greater than 360 degrees is the same as that angle minus a multiple of 360 degrees. For example, 740 degrees is the same as 380 degrees, which is the same as 20 degrees, when it comes to the ending position of something rotated by that much.
Likewise, negative degrees are the same as if you'd added a multiple of 360 degrees to them. -20 degrees is the same as 340 degrees.
There's no magic behind any of these calculations, you just have to pay attention to when something crosses the 0 / 360 degree point on the circle. In the case you describe, you can add 360 to any negative values to express them in positive angles. When subtracting angles, if the ending angle is less than the starting angle, you may also need to add 360 to the result to account for crossing the zero point on the unit circle.
Let's try this again:
There are two angles between A and B. One of them is
θ1 = A - B
The other is
θ2 = 360 - θ1
So just take the minimum of those two.
In addition to Brad Larson's excellent answer I would add that you can do:
CGFloat adjustAngle(angle) { return fmod(angle + 180.0, 360.0); }
...
CGFloat difference = fmod(adjustAngle(angle1) - adjustAngle(angle2), 360.0);
Take the difference, add 360, and mod by 360.