Count the area of the triangle - python

Firstly, the task is to write the code that will count the area of the triangle on the mathematical plane. However not just it, but use in the code the function, that will count the distance between 2 points on the plane.
So, what we have: 6 points like (x1, y1, x2, y2, x3, y3) and we need to write code for the area of the triangle using a function that counts the distance between 2 points on the plane.
P.S: one point = (x1, y1)
What is the problem? IDK
Let's see my code:
def length(x1, y1, x2, y2):
z = (abs(x1 - x2) ** 2 + abs(y1 - y2) ** 2) ** (1/2)
return z
a, b, c, d, e, f = float(input()), float(input()), float(input()), float(input()), float(input()), float(input())
a = length(a, b, c, d)
b = length(a, b, e, f)
c = length(c, d, e, f)
p = a + b + c
ans = (p(p - a)(p - b)(p - c)) ** (1/2)
print(ans)
Unfortunately, I receive a mistake: "'float' object is not callable"
PLZ, help with this code and maybe u will help with input. It is actually strange 6 input() in a row.

In Python, p(p-a) isn't a multiplication: It's an attempt to call a function p with the argument p-a, which, as alexpdev pointed out in their comment, is an error because your p (of type float) isn't a function. You need to explicitly write all the * operators.
ans = (p * (p - a) * (p - b) * (p - c)) ** (1/2)
Also, you got Heron's formula wrong: You've got p = a + b + c, but you need (a + b + c) / 2.

Related

Numpy to solve multi-variable algebraic function

Let's assume we know the following:
a = 1
b = 4
c = 7
d = 2
e = 2
f = 9
With these six variables, we can solve for X, Y, and Z as follows:
X = (b - a) / (d + e)
Y = 2 * np.sin(X/2) * ((c / X) + f)
Z = 2 * np.sin(X/2) * ((a / X) + d)
print(X)
print(Y)
print(Z)
0.75
13.42999273315508
2.4418168605736503
Now, let's flip things around and assume that we're given the values of X, Y, and Z, as well as d, e, and f.
How would we solve for the values of a, b, and c? My algebra is shaky. Is this something that Numpy can handle?
Thanks!
Numpy, no. (Or rather, not as easily, or accurately.)
Sympy, yes.
Declare a, b and c as symbols.
Create expressions that should equal to zero (by moving the left hand side of the equation to the right hand side and changing the sign).
Use sympy.sin instead of math.sin or np.sin.
Use sympy.solve to get the solution of the system.
import sympy
from sympy.abc import a, b, c
X = 0.75
Y = 13.42999273315508
Z = 2.4418168605736503
d = 2
e = 2
f = 9
e1 = (b - a) / (d + e) - X
e2 = 2 * sympy.sin(X/2) * ((c / X) + f) - Y
e3 = 2 * sympy.sin(X/2) * ((a / X) + d) - Z
sympy.solve([e1, e2, e3])
# => {a: 1.00000000000000, b: 4.00000000000000, c: 7.00000000000000}
Solving equations with unknown variables can be done in Sympy.
from sympy import symbols, solve, Eq, sin
a, b, c, d, e, f, X, Y, Z = symbols("a b c d e f X Y Z")
eqns = [
Eq(X, (b - a) / (d + e)),
Eq(Y, 2 * sin(X / 2) * ((c / X) + f)),
Eq(Z, 2 * sin(X / 2) * ((a / X) + d)),
]
assignments = {a: 1, b: 4, c: 7, d: 2, e: 2, f: 9}
print(solve([eq.subs(assignments) for eq in eqns], [X, Y, Z]))
Output:
[(3/4, 110*sin(3/8)/3, 20*sin(3/8)/3)]
To solve for a, b, c just replace X, Y, Z in solve and add their values in the assignments dict.

Mathematical calculation in python abs function

I am trying to create the equation in python.
Sorry in advance if this has already been asked! If so, I couldn't find it, so please share the post!
I run into the problem that I don't know how to code the part in the red square (see equation ).
As I understand it the "|u1|" stands for the absolute value of u1. However, if I code it like the equation is written i.e. abs(u1)abs(u2) I get a syntax error (which I kind of expected).
My problem is the line of code:
angle = np.arccos((Mu1*Mu2)/(abs(Mu1)abs(Mu2)))
My complete code is:
import numpy as np
from math import sqrt
#first direction vector
#punt 1, PQ
# [x,y]
P = (1,1)
Q = (5,3)
#punt 2, RS
R = (2,3)
S = (4,1)
#direction vector = arctan(yq-yp/xq-xp)
#create function to calc direction vector of line
def dirvec(coord1, coord2):
#pull coordinates into x and y variables
x1 , y1 = coord1[0], coord1[1]
x2 , y2 = coord2[0], coord2[1]
#calc vector see article
v = np.arctan((y2-y1)/(x2-x1))
#outputs in radians, not degrees
v = np.degrees(v)
return v
print(dirvec(P,Q))
print(dirvec(R,S))
Mu1 = dirvec(P,Q)
Mu2 = dirvec(R,S)
angle = np.arccos((Mu1*Mu2)/(abs(Mu1)abs(Mu2)))
print(angle)
Thins I tried:
multiply the two abs, but then I'll get the same number (pi) every time:
np.arccos((Mu1*Mu2)/(abs(Mu1)*abs(Mu2)))
+ and - but I cannot imagine these are correct:
np.arccos((Mu1Mu2)/(abs(Mu1)+abs(Mu2))) np.arccos((Mu1Mu2)/(abs(Mu1)-abs(Mu2)))
In the formula, the numerator is the dot product of two vectors, and the denominator is the product of the norms of the two vectors.
Here is a simple way to write your formula:
import math
def dot_product(u, v):
(x1, y1) = u
(x2, y2) = v
return x1 * x2 + y1 * y2
def norm(u):
(x, y) = u
return math.sqrt(x * x + y * y)
def get_angle(u, v):
return math.acos( dot_product(u,v) / (norm(u) * norm(v)) )
def make_vector(p, q):
(x1, y1) = p
(x2, y2) = q
return (x2 - x1, y2 - y1)
#first direction vector
#punt 1, PQ
# [x,y]
P = (1,1)
Q = (5,3)
#punt 2, RS
R = (2,3)
S = (4,1)
angle = get_angle(make_vector(p,q), make_vector(r,s))
print(angle)
From what I see, the result of your code would always be pi or 0. It will be pi if one of the mu1 or mu2 is negative and when both are negative or positive it will be zero.
If I remember vectors properly :
Given two vectors P and Q, with say P = (x, y) and Q = (a, b)
Then abs(P) = sqrt(x^2 + y^2) and P. Q = xa+yb. So that cos# = P. Q/(abs(P) *abs(Q)). If am not clear you can give an example of what you intend to do
Okay so apparently I made a mistake in my interpretation.
I want to thank everyone for your solutions!
After some puzzling it appears that:
import math
import numpy as np
#punt 1, PQ
# [x,y]
P = (1,1)
Q = (5,3)
x1 = P[0]
x2 = Q[0]
y1 = P[1]
y2 = Q[1]
#punt 2, RS
R = (0,2)
S = (4,1)
x3 = R[0]
x4 = S[0]
y3 = R[1]
y4 = S[1]
angle = np.arccos(((x2 - x1) * (x4 - x3) + (y2 - y1) * (y4 - y3)) / (math.sqrt((x2 - x1)**2 + (y2 - y1)**2) * math.sqrt((x4 - x3)**2 + (y4 - y3)**2)))
print(angle)
Is the correct way to calculate the angle between two vectors.
This is obviously not pretty code, but it is the essence of how it works!
Again I want to thank you all for you reaction and solutions!

point-plane distance in SymPy

I was trying to calculate the point-plane distance from point (x_1, y_1, z_1) to the plane ax+by+cz+d=0 in SymPy, but I found the result incorrect. The following is the code I use
from sympy import *
a, b, c, d = symbols('a b c d')
x1, y1, z1 = symbols('x_1 y_1 z_1')
p1 = Point(x1, y1, z1)
plane1 = Plane(Point(0, 0, -d/c), normal_vector=(a, b, c))
plane1.distance(p1)
The correct answer should be \frac{ax_1+by_1+cz_1+d}{\sqrt{a^2+b^2+c^2}}
But SymPy gives me \frac{ax_1+by_1+cz_1+d}{\sqrt{a^2+b^2}}.
This looks like a bug to me. Here is how sympy calculates the distance (method distance(self, o)):
self = plane1
o = p1
x, y, z = map(Dummy, 'xyz')
k = self.equation(x, y, z)
a, b, c = [k.coeff(i) for i in (x, y, z)]
d = k.xreplace({x: o.args[0], y: o.args[1], z: o.args[2]})
t = abs(d/sqrt(a**2 + b**2 + c**2))
If we inspect k and a, b, c we see that the equation's coefficients are not correct:
print(k)
print(a, b, c)
# output:
_x*a + _y*b + c*(_z + d/c)
a b 0
c is zero, which explains your result. This can be fixed by simplifying the equation:
k = simplify(self.equation(x, y, z))
in which case the distance t is as you expected it:
print(t)
# output
Abs((a*x_1 + b*y_1 + c*z_1 + d)/sqrt(a**2 + b**2 + c**2))
Update: This was fixed in the current master of SymPy. See the corresponding issue.

sympy: How to solve this system of transcendental equations?

I'm trying to solve a system of transcendental equations using sympy:
from sympy import *
A, Z, phi, d, a, tau, t, R, u, v = symbols('A Z phi d a tau t R u v', real=True)
system = [
Eq(A, sqrt(R**2*cos(u)**2 + 2*R*d*cos(a)*cos(u) + d**2 + 2*d*(v*sin(tau) - (R*sin(u) + t)*cos(tau))*sin(a) + (v*sin(tau) - (R*sin(u) + t)*cos(tau))**2)),
Eq(Z, v*cos(tau) + (R*sin(u) + t)*sin(tau)),
Eq(phi, (R*sin(a)*cos(u) - (v*sin(tau) - (R*sin(u) + t)*cos(tau))*cos(a))/A),
]
or in euclidian coordinates:
system = [
Eq(A, sqrt(d**2 + 2*d*x*cos(a) + 2*d*(z*sin(tau) - (t + y)*cos(tau))*sin(a) + x**2 + (z*sin(tau) - (t + y)*cos(tau))**2)),
Eq(Z, z*cos(tau) + (t + y)*sin(tau)),
Eq(phi, (x*sin(a) - (z*sin(tau) - (t + y)*cos(tau))*cos(a))/A),
Eq(R**2, x**2+y**2),
]
Essentially this is an intersection of a circle (radius A) with a skewed (angle τ) cylinder (radius R) rotating (angle a) around an eccentric axis (d). I'm interested in the function φ(A, Z) as I need to evaluate it for several hundred combinations of A and Z for a few combinations of the other parameters (R, A, d, t, τ).
Here is what I tried:
Directly using solve(system, [u, v, phi]): Needs too much time to complete.
Reducing it to one equation using first and then using solveset().
Inserting numbers for all parameters (example: R, A, d, t, tao = 25, 150, 125, 2, 5/180*pi) then using any combination of the N() and solve() or solveset().
I was able to get solutions for the simplified problem of the unskewed cylinder (t, tao = 0, 0) with d = sqrt(A**2 - R**2).
How can I solve this system of equations? Failing that: How can I get numeric values for φ for a few dozen combinations of the parameters and a few hundred points (A, Z) each?
If you are interested. Here is the code leading up to the equation:
A, Z, phi, d, a, tau, t, R, u, v = symbols('A Z phi d a tau t R u v', real=True)
r10, z10, phi10 = symbols('r10 z10 phi_10', real=True)
system10 = [Eq(A, r10), Eq(Z, z10), Eq(phi, phi10)]
x9, x8, y8, z8 = symbols('x9 x8 y8 z8', real=True)
system8 = [e.subs(r10, sqrt(x9**2+y8**2)).subs(z10, z8).subs(phi10, y8/A).subs(x9, x8+d) for e in system10]
r6, phi7, phi6, z6 = symbols('r6 phi_7 phi_6 z6', real=True)
system6 = [e.subs(x8, r6*cos(phi7)).subs(y8, r6*sin(phi7)).subs(z8, z6).subs(phi7, phi6+a) for e in system8]
x6, y6 = symbols('x_6 y_6', real=True)
system6xy = [simplify(expand_trig(e).subs(cos(phi6), x6/r6).subs(sin(phi6), y6/r6)) for e in system6]
# solve([simplify(e.subs(phi6, u).subs(r6, R).subs(z6, v).subs(d, sqrt(A**2-R**2))) for e in system6], [u, v, phi]) -> phi = acos(+-R/A)
r5, phi5, x5 = symbols('r_5 phi_5 x_5', real=True)
system5 = [e.subs(x6, x5).subs(y6, r5*cos(phi5)).subs(z6, r5*sin(phi5)) for e in system6xy]
r4, phi4, x4 = symbols('r_4 phi_4 x_4', real=True)
system4 = [e.subs(phi5, phi4 + tau).subs(r5, r4).subs(x5, x4) for e in system5]
x3, y3, z3 = symbols('x_3 y_3 z_3', real=True)
system3 = [expand_trig(e).subs(cos(phi4), y3/r4).subs(sin(phi4), z3/r4).subs(r4, sqrt(y3**2+z3**2)).subs(x4, x3) for e in system4]
x2, y2, z2 = symbols('x_2 y_2 z_2', real=True)
system2 = [e.subs(x3, x2).subs(y3, y2+t).subs(z3, z2) for e in system3]
system = [simplify(e.subs(x2, R*cos(u)).subs(y2, R*sin(u)).subs(z2, v)) for e in system2]
# solve([simplify(e.subs(tau, 0).subs(t, 0).subs(d, sqrt(A**2-R**2))) for e in system], [u, v, phi]) -> phi = acos(+-R/A)
Your first two equations must be solved for u and v; the 3rd then gives the corresponding value of phi. You can easily solve the 2nd for v.
Approach:
Solve the 2nd equation for v and substitute that into the 1st to obtain a function of only u and other variables, the values of which you will define (solving this high order symbolic expression will not be effective). You can't easily solve that equation for u, but you can get a reasonable solution for sin(u) in terms of cos(u) to give two roots: sin(u) = f1(cos(u)) and f2(cos(u)). I get
(Z*sin(tau) + d*sin(a)*cos(tau) - t - sqrt(A**2 - R**2*cos(u)**2 -
2*R*d*cos(a)*cos(u) - d**2*cos(a)**2)*cos(tau))/R
and
(Z*sin(tau) + d*sin(a)*cos(tau) - t + sqrt(A**2 - R**2*cos(u)**2 -
2*R*d*cos(a)*cos(u) - d**2*cos(a)**2)*cos(tau))/R
If we let x = cos(u) we know that f1(x)**2 + x**2 - 1 = 0 (which we call z1(x) and similarly z2(x) for the other root) AND we know that x is constrained to the range of [-1, 1]. So we can bisect zi(x) for x in the range of [-1, 1] to find the value of x; u = asin(x) can be substituted into the second equation to find v; finally, u and v can be substituted into the 3rd to find phi.
e.g. for {tau: 3, R: 7, A: 7, t: 4, a: 3, Z: 3, d: 2}
I get x = sin(u) = {-.704, 0.9886} which gives v = {-1.47, -3.16} and phi = {1.52, -.093}
Of course, those values may be meaningless if the input is meaningless, but with the right values hopefully this approach might prove worthwhile.
/c

Explanation of this code: Determining if a point is on which side of a line

Source: http://datasciencelab.wordpress.com/2014/01/10/machine-learning-classics-the-perceptron/
"The general equation of a line given two points in it, (x1,y2) and (x2,y2), is A + Bx + Cy = 0 where A, B, C can be written in terms of the two points. Defining a vector V = (A, B, C), any point (x,y) belongs to the line if V'x = 0, where x = (1,x,y). Points for which the dot product is positive fall on one side of the line, negatives fall on the other."
I don't quite understand how it works. Also, this line in particular:
self.V = np.array([xB*yA-xA*yB, yB-yA, xA-xB])
Why is Bx determined by yb-ya?
For what its worth, I'm learning Linear Algebra, so I'm quite familiar with the mathematical concept (I realize it is meant to be a normal), but how it is done escapes me.
Why is B determined by yb - ya? (or rather y2 - y1 for our example)
The text assumes the line equation to be: A + B*x + C*y = 0
Let's say we have two points from that line, P1(x1, y1) and P2(x2, y2)
Using the two-points form of the line equation, you will get y - y1 = [(y2 - y1)/(x2 - x1)] * (x - x1) (based on P1and P2)
The same equation, can be developed into [(x2 -x1)*y1 + (y1 - y2)*x1] + (y2 - y1) * x + (x1 - x2) * y = 0
Looking at A + B*x + C*y = 0, you see that:
A, is [(x2 -x1)*y1 + (y1 - y2)*x1] = x2*y1 - y2*x1
B, the coefficient of x is (y2 - y1)
C, the coefficient of y is (x1 - x2)
hence the value np.array([A, B, C]) in the source code appears as np.array([xB*yA - xA*yB, yB - yA, xA - xB])

Categories