I found a python question and facing trouble in solving it correctly.
The question is as follows.
In this problem, you're going to use that class to calculate the net force from a list of forces.
Write a function called find_net_force. find_net_force should have one parameter: a list of instances of Force. The function should return a new instance of Force with the total net magnitude and net angle as the values for its magnitude and angle attributes.
As a reminder:
To find the magnitude of the net force, sum all the horizontal components and sum all the vertical components. The net force is the square root of the sum of the squares of the horizontal forces and the vertical forces (i.e.(total_horizontal2 + total_vertical2)0.5)
To find the angle of the net force, call atan2 with two arguments: the total vertical and total horizontal forces (in that order). Remember to round both the magnitude and direction to one decimal place. This can be done using round(magnitude, 1) and round(angle, 1).
The Force class has three methods: get_horizontal returns a single force's horizontal component. get_vertical returns a single force's vertical component. get_angle returns a single force's angle in degrees (or in radians if you call get_angle(use_degrees=False).
HINT: Don't overcomplicate this. The Force class does a lot of functions except atan2, degrees, and radians.
I tried using the following code to solve it and am getting a different result for the get_angle. I tried changing things with radians, degrees with no correct result.
from math import atan2, degrees, radians, sin, cos
class Force:
def __init__(self, magnitude, angle):
self.magnitude = magnitude
self.angle = radians(angle)
def get_horizontal(self):
return self.magnitude * cos(self.angle)
def get_vertical(self):
return self.magnitude * sin(self.angle)
def get_angle(self, use_degrees = True):
if use_degrees:
return degrees(self.angle)
else:
return self.angle
def find_net_force(force_instances):
total_horizontal = 0
total_vertical = 0
for instance in force_instances:
total_horizontal += float(instance.get_horizontal())
total_vertical += float(instance.get_vertical())
net_force = round((total_horizontal ** 2 + total_vertical ** 2) ** 0.5, 1)
net_angle = round(atan2(total_vertical, total_horizontal), 1)
total_force = Force(net_force, net_angle)
return total_force
force_1 = Force(50, 90)
force_2 = Force(75, -90)
force_3 = Force(100, 0)
forces = [force_1, force_2, force_3]
net_force = find_net_force(forces)
print(net_force.magnitude)
print(net_force.get_angle())
The expected output is:
103.1
-14.0
The actual result I got is:
103.1
-0.2
Update:
Thanks to Michael O. The class was expecting degrees and the function find_net_force was sending the angle in radians. I tried using the conversion to degrees in the find_net_force and it worked.
net_angle = round(degrees(atan2(total_vertical, total_horizontal)), 1)
Thanks to Michael O for helping out in the comments. The class was expecting degrees and the function find_net_force was sending the angle in radians.I tried using the conversion to degrees in the find_net_force and it worked.
net_angle = round(degrees(atan2(total_vertical, total_horizontal)), 1)
Related
Goal:
For a point a and a rectangle B, I would like to calculate the shortest distance between these two objects.
Motivation
Because this calculation is part of the innermost loop of multiple loops, I would like to optimize this calculation as much as possible. With my current python knowledge, making use of dedicated NumPy functions should be the way to goal(?).
Some more details:
The situation is 2D; x,y coordinates
rectangle B is defined by a certain center-of-gravity/mid-point, and width and length (And thus not by a vector of points)
the distance is thus from a to the edges of the rectangle B
My current implementation makes use of the following idea: link. Here the rectangle is divided into multiple subareas. First, it is determined inside which sub-area of B a is located. Hereafter, the calculating the shortest distance between a and B is then straightforward. However, a lot of logic checking is required to determine inside which sub-area a is located. It looks something as following,
def distance_a_to_B(a:Point):
if a in sub_area_1:
return easy_calculation_1(a)
if a in sub_area_2:
return easy_calculation_2(a)
if a in sub_area_3:
return easy_calculation_3(a)
etc
Ideally,
I would like to have an alternative/faster logic checking (Python improvement)
or
a faster mathematical algorithm
Maybe...?
One possible alternative I came up with while writing this question, is to calculate a discrete amount of n points based on Bs chaterestics. From this vector of n points I think it is quite easy use NumPy to:
calculate the shortest distance between a and each point of the n points
find the smallest value of this new vector
For a larger n, this solution would become more precise with a higher performance cost. Do you think this could be a better solution? Or do you have any suggestions for a mathematical (and no approximation) algorithm?
EDIT: added extra clarification, that the distance is towards the edges of the rectangle B
I think, this is a nice implementation of the distance function:
from math import sqrt
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Rectangle:
def __init__(self, center: Point, width: float, height: float):
self.center = center
self.width = width
self.height = height
def distance_to_point(self, point: Point) -> float:
""" assuming that the distance to a point inside of this rect is zero """
dx = abs(self.center.x - point.x) - (self.width * 0.5)
dy = abs(self.center.y - point.y) - (self.height * 0.5)
return sqrt((dx * (dx > 0)) ** 2 + (dy * (dy > 0)) ** 2)
I don't know, how well the Python interpreter translates this code. It is possible, to implement this approach completely branchless, which is a nice property for optimized code.
If you want to compare one point to many rectangles (1:n), you could store all rectangles in a numpy array and compare your point to all rectangles at once using numpy array functions. The same would be possible for n:1 comparison. This could greatly speed up the process!
Without knowing more about your loops I can't provide such a solution, though.
I am making a library for math functions, intended to test and challenge my programming and math skills. A necessary part of this is trig: Sine, Cosine, Tangent, and derivatives/inverses, using degrees or radians.
I have spent hours searching the web for implementation of Taylor Series or CORDIC algorithm using degrees AND/OR radians, to no avail.
def sin(x):
if numerics.degrad == 'deg':
#compute sin(x) using degrees or radians, make sure to return the result in degrees
Please be informed, numerics.degrad is a string value to be referenced from any function in the library or terminal. Usual values are 'deg' or 'rad'. Also, I am trying to avoid importing libraries like numpy or math.
UPDATE: I tried today(11-12-19) to emulate sine by generating a parabola which intersected one waveform. The hope was to check which waveform the angle would land on, then use the according quadratic equation. That did not work. Results in DESMOS were off by up to 0.2 units, and my python implementation was just plain wrong.
# desmos implementation, where y is the output and x is the angle:
# y=0.0001234567901234(x-90)^2+1
# lays closely over a sine wave graphed with y=sin(x).
# here is my python implementation:
def sin(anglein): #return the result of sine of the supplied angle, using the mode
if degrad == 'deg':
const = 0.0001234567901234
angle = anglein
while angle > 360: #should return the corresponding angle within 0-360 degrees
angle -= 360
return((const * ((angle - 90) * (angle - 90))) + 1)
The Taylor series for the sin function is straightforward to implement. Note that any reference which gives a Taylor series for a trigonometric function will assume the input is in radians, unless specified otherwise.
PI = 3.141592653589793238462643383
def sin_taylor_series(x, terms=9):
# map x into the range -PI/2 to PI/2 for greatest accuracy
x %= 2*PI
if x > PI:
x -= 2*PI
if x < -PI/2:
x = -PI - x
elif x > PI/2:
x = PI - x
total = 0
denominator = 1
for i in range(1, 2*terms+2, 2):
denominator *= i
total += (x ** i) / denominator
denominator *= -(i + 1)
return total
At 9 terms, the max absolute error (compared with math.sin) is under 10 ** -15, which is about as good as you're going to get by adding a lot of floating point numbers together.
Note that this is not a particularly efficient way of approximating the sin function.
I have a coordinate system with a certain amount of regions, similar to this one:
The difference in my case is however, that all regions are uniquely numbered, are all of the same size and there are 16 of them (so each quadrant would have 4 slices of exactly the same size).
I also have a set of tuples (two dimensional coordinates), which are all between (-1,-1) and (1,1). I'd now like to check into which region (i.e. 1 to 16) they'd land if mapped onto the coordinate system.
As a total beginner, I have no idea on how to tackle this, but here is my approach so far:
Make all the dividing lines functions and check for each point whether they're above and below them. Ignore those on the decision boundary
For example: Quadrant 1 has four regions. From the x-axis to the y-axis (counter-clockwise) let's call them a, b, c and d.
a would be the region between the x-axis and f1(x) = 0.3333x (red)
b between f1 and f2, f2(x) = x (yellow)
c between f2 and f3, f3(x) = 3x (blue)
d between f3 and the y-axis
As code:
def a(p):
if(y > 0 and y < 0.3333x):
return "a"
else:
b(p)
def b(p):
if(y > 0.3333x and y < x)
return "b"
else:
c(p)
def c(p):
if(y > x and y < 3x):
return "c"
else:
d(p)
def d(p):
if(y > 3x and x > 0):
return "d"
Note: for readability's sake I just wrote "x" and "y" for the tuple's respective coordinates, instead p[0] or p[1] every time. Also, as stated above, I'm assuming that there are not items directly on the functions, so those are ignored.
Now, that is a possible solution, but I feel like there's almost certainly a more efficient one.
Since you're working between (-1,-1) and (1,1) coordinates and divinding equaly the cartesian plane, it becomes naturally to use trigonometry functions. Thinking in the unitary circle, which has 2*pi deegres, you are dividing it in n equal parts (in this case n = 16). So each slice has (2*pi)/16 = pi/8 deegres. Now you can imagine an arbitray point (x, y) connected to the origin point (0, 0), it formes an angle with the x-axis. To find this angle you just need to calculate the arc-tangent of y/x. Then you just need to verify in which angle section it is.
Here is a sketch:
And to directly map to the interval you can use the bisect module:
import bisect
from math import atan2
from math import pi
def find_section(x, y):
# create intervals
sections = [2 * pi * i / 16 for i in range(1, 17)]
# find the angle
angle = atan2(y, x)
# adjusts the angle to the other half circle
if y < 0:
angle += 2*pi
# map into sections
return bisect.bisect_left(sections, angle)
Usage:
In [1]: find_section(0.4, 0.2)
Out[1]: 1
In [2]: find_section(0.8, 0.2)
Out[2]: 0
Shapely is a python library that can help you with typical cartesian geometry, but as far as I know it doesn't have an easy way of extending its Line objects indefinitely based on a function.
If you're ok with that, then you can check if any Point is in any Polygon using the Polygon.contains(Point) pattern, as shown here: https://shapely.readthedocs.io/en/stable/manual.html#object.contains
Hi recently I was writing a program with a bunch dots that the player had to avoid. The dots changed direction, but can't turn too much in a given timeframe.
I had a method of doing this but was inefficient as I had to arcsine, knowing the cosed angle and sined angle, then sine and cosine that angle. I thought of just returning the cosine and sined angle, but theres one problem. Once I received the cosine and sine, I need too know if it is too different from my current state.
With the angle this would be easy as I would just have too see the difference, here's a model program,(the code I currently have uses the angle, and isn't very helpful). I have tried graphing sine and cosine and trying to observe any patterns, none obvious showed up.
import math
def sendTargRot():
#I actually use a fairly long method to find it's current rotation, but a random.random() is a fair replacement, so in my real thing there would be no angle calculation
pretendAngle = math.pi*random.random()-math.pi
pretendCosedX = math.cos(pretendAngle)
pretendSinedX = math.sin(pretendAngle)
def changeDotAngle():
targRot = sendTargRot
#make sure targRot is not too much from current rotation
#do stuff with the angle, change dot's rotation
If you want to just give me an algorithm without code that is just as acceptable!
EDIT: I can't really change sendTargRot so it gives a proper rotation, because that would require me knowing the current angle, and really it's just moving the problem.
To get angle between two vectors you can use atan2 function
angle = Math.atan2(a.x * b.y - a.y * b.x, a.x * b.x + a.y * b.y)
if you already have got cosines and sines (the same as coordinates on unit circle):
angle = Math.atan2(cos(a) * sin(b) - sin(a) * cos(b), cos(a) * cos(b) + sin(a) * sin(b))
This approach gives angle needed to rotate a until it coincides with b accounting for direction (in range -Pi..Pi)
I am just starting out with programming and this assignment is giving me a lot of trouble. How do I change the Monte Carlo code below (used for area under a curve) so that it estimates pi?
from random import uniform
from math import exp
def estimate_area(f, a, b, m, n=1000):
hits = 0
total = m * (b - a)
for i in range(n):
x = uniform(a, b)
y = uniform(0, m)
if y <= f(x):
hits += 1
frac = hits / n
return frac * total
def f(x):
return exp(-x**2)
def main():
print(estimate_area(f, 0, 2, 1))
main()
Any help would be greatly appreciated. Thank you.
I won't solve this for you, but I will give you a hint. Think about embedding a unit circle within a 2x2 square, and about how that might help you to estimate π. Once you figure that out, make use of the inherent symmetries to work with just one of the four quadrants.
This is a common example for Monte Carlo methods, see for example the Wikipedia page on Monte Carlo Method.
Think about this problem in only one quadrant, so a quarter of a circle centered at 0,0 and the radius of 1 and a square from (0,0) to (1,1).
If you randomly put a point in the square at x=uniform(0,1) and y=uniform(0,1), you can check if the point falls within the quarter circle, (x^2.+y^2.)^0.5 <= 1.0.
The chances this happens is related to the ratio of the volumes of the two objects.