Python convert angles between two different planes of coordinates? - python

I do not know how to word my problem , but I am mostly interested on the logic I could use in python, since my knowledge in python is not that much regarding usage of math.
I have 2 different planes, one is fixed where North is always 0, east is 90 , south is 180, and west is 270. I have another plane of reference too where 0 is always in front of me.
Now for me this sound simple in math in my mind and in paper, but in python I just dont have a good graps on how to reflect this, wherever I am facing, its always 0 in my own plane of reference, however in the other plane of reference (north, east, south, west) I am facing any angle. And for example, lets say I have something at 70 degrees in my own plane of reference, and I know that in the Compass reference I am facing to 270 degrees (which means that at 0 degrees in my reference, i am facing to 270 degrees in compass), I want to determine at which angle (compass) is an object that in my own plane of reference is at around 170 degrees. Mathematically,I can do this by simply adding 100 degrees to Compass reference, and once I reach 360 I go back to 0 . so that means that the object is at 10 degrees in compass.
I know the answer would be simple in terms of programming , maybe an if degrees > 360, then degrees = 0. But no idea if there is an easier way in python to consider all cases (degrees <0, degrees >0) .

You can use the modulo operator which returns the remainder of a division:
calculated_angle %= 360 # will keep the value between 0 & 359
So once your calculated angle (acheived by adding the angle from your frame of reference + the one on your compass) is stored in calculated_angle.
You can use the modulo operator to ensure that if the angle exceeds 360 deg, it returns back to 0 and starts counting up again. So 460 % 360 would be 100. And if the angle goes below 0, it starts back up from 360 again. So -50 % 360 would be 310.

Related

Using .isel() to select noncontinuous range of data with xarray

I'm working with MERRA-2 data using xarray, and I'm attempting to plot data only over the Pacific Ocean. However, my data are in units of degrees East, such that the International Dateline is represented with index 0 and a value of -180, and the Prime Meridian/Greenwich Meridian is at index 288 (576/2) with a value approximating zero. To a rough estimation, the Pacific Ocean can be found in this coordinate system between 0 and 96, as well as from 480 to 575 (these indices corresponded to 120 E and 120 W, respectively.) How can I use .isel() (or .loc() or .sel(), if one of those is more appropriate) to choose JUST the region I'm describing?
For reference, the below picture is the result of using data.isel(lon=slice(96,480)).plot(), which is my current best guess. Do I need to use a cyclic point? To my understanding, that would solve the opposite problem I have.

How to calculate the spatial elevation angle (depression or looking up) to look up the antenna gain of theta and phi?

Ok so this is a relatively complex problem:
Imagine the following situation:
UAV-Coordinates are: (50, 50, 80) (x,y,z in metres)
Basestation Coordinates are: (50, 100, 80) (x,y,z in metres)
Both, the UAV and the base station are fitted with an antenna that has a directivity. The UAV's antenna is looking straight north (to the BS) and the BS's antenna is looking south (to the UAV in this case).
When I now move the UAV to the Basestation, the depression angle is getting higher and higher until the drone is overtaking the basestation.
My data for the antenna gains (for both antennas) is given in the following CSV format:
HOR_ANGLE; HOR_GAIN; VERT_ANGLE; VERT_GAIN
The angles are in range of zero to 359 degrees and each angle has a corresponding gain value.
My problem is that I need to get the gain of both antennas for the respective angles of directivity (azimuth) and elevation/depression. The antenna diagram is looking in the following way: 1 You can see that it is not symmetrical. To obtain the horizontal angle is not a problem, I calculated it the following way:
dx = object2[0] - object1[0]
dy = object2[1] - object1[1]
angle_radians = math.atan2(dy, dx)
angle_degree = math.degrees(angle_radians)
angle = angle_degree - 90
if angle < 0:
angle = abs(angle)
else:
angle = 360 - angle
angle = angle - start
if angle < 0:
angle = 360 + angle
Where object 1 or object 2 is either the drone or the base station and Index 0 is the longitude in metres and Index 1 is the latitude in metres. The start is the horizontal angle of the main beam of the antenna.
The problem now occurs when calculating the vertical angle. Because the Pythagorean theorem (calculating the angle with arcus cosine or arcus sine respectively) is not intelligent, it always maps the vertical angle into an interval of -90 to 90 degrees. But I need the angle in the interval of 0 to 359 to get the gain out of the CSV. As you can see in the picture 1 on the right side, there occurs the mapping. The left red dot is theoretically behind the base station so the angle should be (roundabout) 110 degrees. When using the Pythagorean theorem the angle is 70 degrees, which is wrong. This is what I mean with mapping.
When I now implement a restriction for the calculation of the vertical angle in the following way:
if 90 < hor_angle < 270:
vert_angle = vert_angle + 180
I now have the problem of a very "hard" border of the horizontal angles as one can see in this picture: 2 This picture shows the UAV from the top (up is north). You can see the directivity of the antenna heading north. Now, because of my implemented restriction, every pixel (or base station) being behind the drone has a very weak antenna gain. In the real world, the "cut" of those values is more dynamic and not so harsh. The following picture shows a 3D diagram of an antenna pattern: 3
I already tried to map the vertical angle to a range of 90 and -90 degrees respective to the horizontal angle but that did not solve the problem.
To put it in a nutshell my question is: How can I calculate the vertical depression or elevation angle (where 0 degree is right and the angles range from 0 to 359 degrees clockwise) with respect to the horizontal angle of the objects dynamically (both for the UAV's and base station's antenna)?
I hope the problem is expressed in an understandable way. I am looking forward to hearing your ideas and follow-up questions or remarks.

I have the following python problem for school, but I don't even have a clue where to begin with

At the origin of the coordinate system we place a circle with radius 1 and a square with radius 1, that is, with page 2.
The plane of the circle is πr2, so π, and the square of the square is a2, that is, 4. The square of the square covered with the circle is π / 4.
Choose two random coordinates within the square, i.e. two random numbers between -1 and 1. The probability that this point lies within the circle is equal to π / 4.
We do this a thousand times. There will be around n = 1000 × π / 4 points within the circle. If they did not know how much it was, they could actually do this experiment; with them we get the upper n, and from this n, if we turn the formula around, we calculate the value of π.
Write a program that draws out 1000 random coordinates within a square, (quietly) counts how much it is calculated in this way within the circle and in the end.
This will help you: if you write from random random * at the beginning of the program, the random () function returns a random number between 0 and 1. How to convert it into numbers between -1 and 1, consider it yourself. You also deal with mathematics yourself.
enter image description here
Rather than giving you a complete answer... as this is a school project, that would deprive you of some learning. I'll give you some pointers:
If you need random numbers between -1 and 1, but random.random() only gives values between 0 and 1. What do you need to do to the random numbers to get the range you need? (One simple way would be to multiply by 2 - resulting in a number between 0 and 2, then subtract by 1, to bring it to -1 to 1)
Try pyplot for plotting the graph so you can visualise the answer to check to see if your doing the right thing.

Fall-off function for mountains

I am writing mincraft-like game with voxel terrain.
For mountains, I specify a location, a height and size. There is a function to return True if the block at the current (x, y, z) coordinate is part of a mountain. If a block is far away from the centre of a mountain, True is only returned if if the z coord is below a maximum height for the distance from the mountain, ie the further from a mountain a block is, the lower the maximum height. So at the centre of a mountain, the maximum height is high, and True will be returned even if the z is high (I am using a z-up system). However, further away from the mountain, the maximum height will be lower.
However, my current function (below) returns them linearly, and real mountains do not have straight sides:
def isMountain(self, x, y, z, mountainPos, mountainSize, mountainHeight):
if math.hypot(mountainPos[0] - x, mountainPos[1] - y) < mountainSize:
if z < (mountainHeight - math.hypot(mountainPos[0] - x, mountainPos[1] - y)):
return True
else:
return False
The line 3 checks if z is less than the maximum height for the position, if yes, returning True, otherwise, False.
These are the maximum heights for distances:
Distance: Max Height
0 - 10
1 - 9
2 - 8
...
9 - 1
10 - 0
How could I re-write this function to make it return more mountain-like values: not linear, rather cubic or smooth fall-off (like blender proportianal edit mode), so it would give values more like this:
0 - 10
1 - 9
2 - 9
3 - 8
4 - 7
5 - 5
6 - 3
7 - 1
You can either break your head to find out some mathematical formula for this, or you could simulate the natural erosion process.
This is usually done using a grid (matrix, cells, ...) and iterating.
Basically you would start with more or less random high terrain, then erode it until mountains form, well actually mountains are what remains.
That said, this is usually more costly than using a simple function, but on modern computers this would work well.
Also see: https://www.gamasutra.com/blogs/MattKlingensmith/20130811/198049/How_we_Generate_Terrain_in_DwarfCorp.php
If you were interested in going another route you could use a modified version of perlin noise to use amplitude and frequency then use smoothing transition to get what you want. You could set points to have a general height range and then let the noise algo do its thing to create variability between the points. I have done something similar for creating an inf gen world with different biomes that have different kinds of mountain heights and shapes.
Maybe you could use an inverse tan function like this
https://www.desmos.com/calculator/sn7tbepuxh
Where h is the max height, s is the steepness and x is the distance from the centre of the peak. The -1 at the end allows negative values to be ignored so that the base of the mountain won't extend forever.
I've used this for a mountain generator for a small game and it seems to work fine, just as long as you tweak your steepness and height values to the mountain isn't too spiky.

Point wrapping algorithm - A blocked Swinging door

I'm trying to some some code in python. Basically what it does is simulates a door (viewed from above) on an (x,y) coordinate system. The task is given a list of points, determine which the door will hit first, if any.
Determining if a point is within range to be hit by the door is simple enough, determining which point gets hit first is proving to be difficult, as the door can swing clockwise or counter clockwise, and has a rather large, and variable range of swing (in terms of radians/degrees). The issue is mostly that I'm not sure what conditions need to be true for the point to be hit first.
Update:
I do have the angles calculated, but concerned about special cases such as when the door is at 1 degree, and swinging clockwise towards points at angles 180, 190, and 300 for example.
Calculate the angle from the door hinge to each of the points; whichever is closest to the current angle of the door itself (hinge to door edge) will be hit first when rotating.
If the cycling is giving you trouble: notice that for any given angle, you can subtract it from 360 to get its complement; whichever is the smaller of the two is the closer way to get to it. So:
Calculate all angles for the points a1 ... aN
Subtract them all from the door angle to get difference angles d1...dN
Replace each dN with min( dN, 360 - dN ) to get the "shorter" approach
Pick the minimum
This can be simplified if you think in terms of the difference between the angle of door and the angle of each point relative to the hinge of the door.
You then find the angle with this formula:
length of vector from hinge to door: A
length of vector from hinge to point: B
angle = (A * B)/(A^2 + B^2)

Categories