Split a list of Azimuth into two groups equally - python

I'm trying to make a program to get azimuth value from two points using this code:
import math
def azimuth(x1, x2, y1, y2):
temp = (y2 - y1) / (x2 - x1)
res = math.degrees(abs(math.atan(temp)))
if x2 > x1 and y2 > y1: #Q1
res = 90 - res
elif x2 < x1 and y2 > y1: #Q2
res = (90 - res) * -1
elif x2 < x1 and y2 < y1: #Q3
res = (90 + res) * -1
elif x2 > x1 and y2 < y1: #Q4
res += 90
else:
raise ValueError('No point difference.')
return res
I've been able to get azimuth value with range (-180)-180. Next, I need to split it into two groups of azimuth value equaly based on range of value. The goal is to get two group which get the closest azimuth value.
The problem is that pairs of points on quadrant III ((-180)-(-90)) and quadrant IV (90-180) logically can be consider as close (e.g:(-179) and 179). About how to split it equally, I've been thinking of using sorted list of azimuth and using index idx = int(math.ceil((len(lst)-1)/2)) as the median to split the list. This is how I do it on code:
lst = [-60, -50, -40, -30, -20, -10, 10, 20, 30, 40, 50, 60]
def split_list(lst):
lst.sort()
idx = int(math.ceil((len(lst)-1)/2))
left = []
right = []
for i in lst:
if i < lst[idx]:
left.append(i)
else:
right.append(i)
print(left)
print(right)
return left, right
split_list(lst)
The code above will return list [-60, -50, -40, -30, -20, -10] and [10, 20, 30, 40, 50, 60] as the result.
Is there any idea of how to do this? With the current condition, I don't have any idea of how to make quadrant III and IV considered as close.

You might be interested in math.atan2(y, x).
The point of atan2() is that the signs of both inputs are known to it,
so it can compute the correct quadrant for the angle.
Which means that you can remove all the quadrant logic from your code, and basically replace the whole function with math.degrees(math.atan2(y2 - y1, x2 - x1)). It also avoids a division by 0 if x1 == x2.
If you have two azimuths, you can calculate the minimum rotation between both with:
def shortest_rotation(start_angle, end_angle):
return (end_angle - start_angle + 180) % 360 - 180
You can split the list of azimuths depending on the sign of the output.
Just for fun, here's a small script to split azimuths left and right of split_at_azimuth, and display them on a polar plot:
def shortest_rotation(start_angle, end_angle):
return (end_angle - start_angle + 180) % 360 - 180
azimuths = list(range(0, 370, 10))
split_at_azimuth = 60
left, right = [], []
for azimuth in azimuths:
(left, right)[shortest_rotation(azimuth, split_at_azimuth) >= 0].append(azimuth)
import numpy as np
import matplotlib.pyplot as plt
t1 = [np.pi * a / 180 for a in right]
t2 = [np.pi * a / 180 for a in left]
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(t1, [1 for _ in t1], '+')
ax.plot(t2, [1 for _ in t2], '+')
ax.set_rmax(2)
ax.set_rticks([])
ax.grid(True)
ax.set_title("Left and right azimuth", va='bottom')
plt.show()

Your problem can be reduced to finding a distance between two phase points. I say phase because phase is wrapped (in your case % 360). Thus, you need to compare the distance both ways: clockwise and counter-clockwise. The simplest might be:
dist = min(abs(A2-A1), abs(360+A1-A2)) # requiring A1 <= A2
If the clockwise distance is the smallest, then the first term in min() will be your solution. If counter-clockwise, then the second term in min() will be your solution. To do grouping, you'd then calculate the distances between desired points. Note that arrays don't need to be sorted for this to work, just that A1 <= A2.

Related

How to pick a random point from one of the sides of a pentagon?

In my program, I have 5 coordinates. In Python, I want to connect the 5 points together to form a pentagon, and know which points were connected to form each side. My goal is to then pick a random point from one of the sides of the pentagon. Does anyone know how I could write this in Python? I tried reading about convex hull but wasn't able to achieve anything, and I'm not sure if that is necessary for this problem. Thanks!
You can use the following to generate a point on a line segment:
x0 = x1 + a * (x2 - x1)
y0 = y1 + a * (y2 - y1)
, where (x1, y1) and (x2, y2) are start and end points of the segment and a is a number between 0 and 1.
Now, to solve your problem, you need two random numbers. First an integer to select a random side of the pentagon, and then a float between 0 and 1 to generate a random point on that side:
import random as rnd
i = rnd.randrange(5)
j = (i+1) % 5
t = rnd.uniform(0, 1)
x = [0, 1, 2, 3, 4]
y = [4, 3, 2, 1, 0]
x0 = x[i] + t * (x[j] - x[i])
y0 = y[i] + t * (y[j] - y[i])
print(i, j, t, x0, y0)

How to get correct Angle using python

I am try to find the angle of line
i know the coordinate points
Start Point : 404, 119
Mid Point : 279, 214
End Point : 154, 310
import numpy as np
def findangle(x1,y1,x2,y2,x3,y3):
ria = np.arctan2(y2 - y1, x2 - x1) - np.arctan2(y3 - y1, x3 - x1)
webangle = int(np.abs(ria * 180 / np.pi))
return webangle
result
Its return 270. But actual angle is 85-90.
Now, I want formula to calculate the angle (Either i Will rotate the image clockwise or Anticlockwise that time also return actual angle) in python code
I think you need to adjust the returned angle based on the range you wish the result to be in.
The following assumes you desire results between -180 (inclusive) and 180 (exclusive).
def adjust(a, degrees=True):
v = 180 if degrees else np.pi
return (a + v) % (2 * v) - v
def angle(p, degrees=True):
assert p.shape == (3, 2), 'p should have 3 points, in 2D'
yx = p[:, ::-1]
a0 = np.arctan2(*(yx[1] - yx[0]))
a1 = np.arctan2(*(yx[2] - yx[1]))
a = np.rad2deg(a1 - a0) if degrees else a1 - a0
return adjust(a, degrees)
And here is some code to test validity:
def rot(a, degrees=True):
a = np.deg2rad(a) if degrees else a
sa, ca = np.sin(a), np.cos(a)
return np.array([[ca, sa], [-sa, ca]])
def genp(angle, initial=0, lengths=(1, 1), degrees=True):
p0 = np.array((0, 0))
p1 = np.array((lengths[0], 0))
p2 = p1 + np.array((lengths[1], 0)) # rot(angle, degrees=degrees)
p = np.vstack((p0, p1, p2)) # rot(initial, degrees=degrees)
return p
def plot_problem(p, ax=None):
ax = plt.gca() if ax is None else ax
ax.plot(*p.T, '-o')
for s, xy in zip(list('abc'), p):
ax.annotate(s, xy, xytext=(0, 5), textcoords='offset points')
ax.set_aspect('equal')
Example:
p = genp(60, initial=30, lengths=(2, 1))
>>> angle(p)
60.0
plot_problem(p)
Now, a stress test:
n = 1000
np.random.seed(0)
for _ in range(n):
a = np.random.uniform(-180, 180)
initial = np.random.uniform(-180, 180)
lengths = np.random.uniform(1, 10, size=2)
p = genp(a, initial, lengths)
ahat = angle(p)
assert np.allclose(a, ahat)
Which passes.
It's a simple math. The numpy.arctan2() returns a value in the range [-π, π]. So a difference of two values is in the range [-2π, 2π], and the absolute value of that is in the range [0, 2π]. You want an angle x in the range [0, π], and x is equivalent to (2π - x) in your context. So you can take x if x < π, and take (2π - x) otherwise.
So, just do like this using min() for example.
def findangle(x1,y1,x2,y2,x3,y3):
...
return min(webangle, 360 - webangle)
As a side note, you don't need to use Numpy functions for a scalar input. Just use the math.atan2() and math.fabs().

Missalgined circles in Fourier Series/Transform using Python and Tkinter

I made a Fourier Series/Transform Tkinter app, and so far everything works as I want it to, except that I am having issues with the circles misaligning.
Here is an image explaining my issue (the green and pink were added after the fact to better explain the issue):
I have narrowed down the problem to the start of the lines, as it seems that they end in the correct place, and the circles are in their correct places.
The distance between the correct positions and the position where the lines start seems to grow, but is actually proportional to the speed of the circle rotating, as the circle rotates by larger amounts, thus going faster.
Here is the code:
from tkinter import *
import time
import math
import random
root = Tk()
myCanvas = Canvas(root, width=1300, height=750)
myCanvas.pack()
myCanvas.configure(bg="#0A2239")
global x,y, lines, xList, yList
NumOfCircles = 4
rList = [200]
n=3
for i in range(0, NumOfCircles):
rList.append(rList[0]/n)
n=n+2
print(rList)
num = 250/sum(rList)
for i in range(0, NumOfCircles):
rList[i] = rList[i]*num
x=0
y=0
lines = []
circles = []
centerXList = [300]
for i in range(0,NumOfCircles):
centerXList.append(0)
centerYList = [300]
for i in range(0,NumOfCircles):
centerYList.append(0)
xList = [0]*NumOfCircles
yList = [0]*NumOfCircles
waveLines = []
wavePoints = []
con=0
endCoord = []
for i in range(0, NumOfCircles):
endCoord.append([0,0])
lastX = 0
lastY = 0
count = 0
randlist = []
n=1
for i in range(0, NumOfCircles):
randlist.append(200/n)
n=n+2
def createCircle(x, y, r, canvasName):
x0 = x - r
y0 = y - r
x1 = x + r
y1 = y + r
return canvasName.create_oval(x0, y0, x1, y1, width=r/50, outline="#094F9A")
def updateCircle(i):
newX = endCoord[i-1][0]
newY = endCoord[i-1][1]
centerXList[i] = newX
centerYList[i] = newY
x0 = newX - rList[i]
y0 = newY - rList[i]
x1 = newX + rList[i]
y1 = newY + rList[i]
myCanvas.coords(circles[i], x0, y0, x1, y1)
def circleWithLine(i):
global line, lines
circle = createCircle(centerXList[i], centerYList[i], rList[i], myCanvas)
circles.append(circle)
line = myCanvas.create_line(centerXList[i], centerYList[i], centerXList[i], centerYList[i], width=2, fill="#1581B7")
lines.append(line)
def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
myCanvas.coords(lines[i], x, y, endCoord[i][0], endCoord[i][1])
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])
def lineBetweenTwoPoints(x, y, x2, y2):
line = myCanvas.create_line(x, y, x2, y2, fill="white")
return line
def lineForWave(y1, y2, y3, y4, con):
l = myCanvas.create_line(700+con, y1, 702+con, y2, 704+con, y3, 706+con, y4, smooth=1, fill="white")
waveLines.append(l)
for i in range(0,NumOfCircles):
circleWithLine(i)
myCanvas.create_line(700, 20, 700, 620, fill="black", width = 3)
myCanvas.create_line(700, 300, 1250, 300, fill="red")
myCanvas.create_line(0, 300, 600, 300, fill="red", width = 0.5)
myCanvas.create_line(300, 0, 300, 600, fill="red", width = 0.5)
while True:
for i in range(0, len(lines)):
update(i, centerXList[i], centerYList[i])
for i in range(1, len(lines)):
updateCircle(i)
if count >= 8:
lineBetweenTwoPoints(lastX, lastY, endCoord[i][0], endCoord[i][1])
if count % 6 == 0 and con<550:
lineForWave(wavePoints[-7],wavePoints[-5],wavePoints[-3],wavePoints[-1], con)
con += 6
wavePoints.append(endCoord[i][1])
myCanvas.update()
lastX = endCoord[i][0]
lastY = endCoord[i][1]
if count != 108:
count += 1
else:
count = 8
time.sleep(0.01)
root.mainloop()
I am aware that this is not the best way to achieve what I am trying to achieve, as using classes would be much better. I plan to do that in case nobody can find a solution, and hope that when it is re-written, this issue does not persist.
The main problem that you are facing is that you receive floating point numbers from your calculations but you can only use integers for pixels. In the following I will show you where you fail and the quickest way to solve the issue.
First your goal is to have connected lines and you calculate the points here:
def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
myCanvas.coords(lines[i], x, y, endCoord[i][0], endCoord[i][1])
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])
when you add the following code into this function you see that it fails there.
if i != 0:
print(i,x,y)
print(i,endCoord[i-1][0], endCoord[i-1][1])
Because x and y should always match with the last point (end of the previous line) that will be endCoord[i-1][0] and endCoord[i-1][1].
to solve your problem I simply skipt the match for the sarting point of the follow up lines and took the coordinates of the previous line with the following alternated function:
def update(i, x, y):
endCoord[i][0] = x+(rList[i]*math.cos(xList[i]))
endCoord[i][1] = y+(rList[i]*math.sin(yList[i]))
if i == 0:
points = x, y, endCoord[i][0], endCoord[i][1]
else:
points = endCoord[i-1][0], endCoord[i-1][1], endCoord[i][0], endCoord[i][1]
myCanvas.coords(lines[i], *points)
xList[i] += (math.pi/randlist[i])
yList[i] += (math.pi/randlist[i])
Additional proposals are:
don't use wildcard imports
import just what you really use in the code random isnt used in your example
the use of global in the global namespace is useless
create functions to avoid repetitive code
def listinpt_times_circles(inpt):
return [inpt]*CIRCLES
x_list = listinpt_times_circles(0)
y_list = listinpt_times_circles(0)
center_x_list = listinpt_times_circles(0)
center_x_list.insert(0,300)
center_y_list = listinpt_times_circles(0)
center_y_list.insert(0,300)
use .after(ms,func,*args) instead of a interrupting while loop and blocking call time.sleep
def animate():
global count,con,lastX,lastY
for i in range(0, len(lines)):
update(i, centerXList[i], centerYList[i])
for i in range(1, len(lines)):
updateCircle(i)
if count >= 8:
lineBetweenTwoPoints(lastX, lastY, endCoord[i][0], endCoord[i][1])
if count % 6 == 0 and con<550:
lineForWave(wavePoints[-7],wavePoints[-5],wavePoints[-3],wavePoints[-1], con)
con += 6
wavePoints.append(endCoord[i][1])
myCanvas.update_idletasks()
lastX = endCoord[i][0]
lastY = endCoord[i][1]
if count != 108:
count += 1
else:
count = 8
root.after(10,animate)
animate()
root.mainloop()
read the PEP 8 -- Style Guide for Python
use intuitive variable names to make your code easier to read for others and yourself in the future
list_of_radii = [200] #instead of rList
as said pixels will be expressed with integers not with floating point numbers
myCanvas.create_line(0, 300, 600, 300, fill="red", width = 1) #0.5 has no effect compare 0.1 to 1
using classes and a canvas for each animation will become handy if you want to show more cycles
dont use tkinters update method
As #Thingamabobs said, the main reason for the misalignment is that pixel coordinates work with integer values. I got excited about your project and decided to make an example using matplotlib, this way I do not have to work with integer values for the coordinates. The example was made to work with any function, I implemented samples with sine, square and sawtooth functions.
I also tried to follow some good practices for naming, type annotations and so on, I hope this helps you
from numbers import Complex
from typing import Callable, Iterable, List
import matplotlib.pyplot as plt
import numpy as np
def fourier_series_coeff_numpy(f: Callable, T: float, N: int) -> List[Complex]:
"""Get the coefficients of the Fourier series of a function.
Args:
f (Callable): function to get the Fourier series coefficients of.
T (float): period of the function.
N (int): number of coefficients to get.
Returns:
List[Complex]: list of coefficients of the Fourier series.
"""
f_sample = 2 * N
t, dt = np.linspace(0, T, f_sample + 2, endpoint=False, retstep=True)
y = np.fft.fft(f(t)) / t.size
return y
def evaluate_fourier_series(coeffs: List[Complex], ang: float, period: float) -> List[Complex]:
"""Evaluate a Fourier series at a given angle.
Args:
coeffs (List[Complex]): list of coefficients of the Fourier series.
ang (float): angle to evaluate the Fourier series at.
period (float): period of the Fourier series.
Returns:
List[Complex]: list of complex numbers representing the Fourier series.
"""
N = np.fft.fftfreq(len(coeffs), d=1/len(coeffs))
N = filter(lambda x: x >= 0, N)
y = 0
radius = []
for n, c in zip(N, coeffs):
r = 2 * c * np.exp(1j * n * ang / period)
y += r
radius.append(r)
return radius
def square_function_factory(period: float):
"""Builds a square function with given period.
Args:
period (float): period of the square function.
"""
def f(t):
if isinstance(t, Iterable):
return [1.0 if x % period < period / 2 else -1.0 for x in t]
elif isinstance(t, float):
return 1.0 if t % period < period / 2 else -1.0
return f
def saw_tooth_function_factory(period: float):
"""Builds a saw-tooth function with given period.
Args:
period (float): period of the saw-tooth function.
"""
def f(t):
if isinstance(t, Iterable):
return [1.0 - 2 * (x % period / period) for x in t]
elif isinstance(t, float):
return 1.0 - 2 * (t % period / period)
return f
def main():
PERIOD = 1
GRAPH_RANGE = 3.0
N_COEFFS = 30
f = square_function_factory(PERIOD)
# f = lambda t: np.sin(2 * np.pi * t / PERIOD)
# f = saw_tooth_function_factory(PERIOD)
coeffs = fourier_series_coeff_numpy(f, 1, N_COEFFS)
radius = evaluate_fourier_series(coeffs, 0, 1)
fig, axs = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(10, 5))
ang_cum = []
amp_cum = []
for ang in np.linspace(0, 2*np.pi * PERIOD * 3, 200):
radius = evaluate_fourier_series(coeffs, ang, 1)
x = np.cumsum([x.imag for x in radius])
y = np.cumsum([x.real for x in radius])
x = np.insert(x, 0, 0)
y = np.insert(y, 0, 0)
axs[0].plot(x, y)
axs[0].set_ylim(-GRAPH_RANGE, GRAPH_RANGE)
axs[0].set_xlim(-GRAPH_RANGE, GRAPH_RANGE)
ang_cum.append(ang)
amp_cum.append(y[-1])
axs[1].plot(ang_cum, amp_cum)
axs[0].axhline(y=y[-1],
xmin=x[-1] / (2 * GRAPH_RANGE) + 0.5,
xmax=1.2,
c="black",
linewidth=1,
zorder=0,
clip_on=False)
min_x, max_x = axs[1].get_xlim()
line_end_x = (ang - min_x) / (max_x - min_x)
axs[1].axhline(y=y[-1],
xmin=-0.2,
xmax=line_end_x,
c="black",
linewidth=1,
zorder=0,
clip_on=False)
plt.pause(0.01)
axs[0].clear()
axs[1].clear()
if __name__ == '__main__':
main()

is there any way to check if a line output of LSD is vertical or horizontal

I am using LSD: LineSegmentDetector in python and OpenCV, now the problem is I want to count num of horizontal lines detected and number of vertical lines detected.
img = cv2.imread("test/images.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 100, 200, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
linesL = lsd(gray)
for line in linesL:
x1, y1, x2, y2, width = map(int,line)
length = line_length(x1,y1,x2,y2)
if line[-1]<3:
lines_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,0),1)
show_img(lines_img,"FLD")
Lines Array [[x1,y1,x2,y2,width],....]
I have tried morphological operations and houghlinesP as well but they aren't performing well.
We can use slope for this problem. We know the the slope of a line in angles would be the arctan of the ration of difference of ys and xs
slope_as_angle = atan((y1 - y2) / (x1 - x2))
It's a good practice to use atan2 instead of atan. and for simplicity let's use degrees instead of radians:
slope_as_angle = math.degrees(math.atan2((y1 - y2), (x1 - x2)))
Now let's see how lines would look like for different slope angles:
for i in range(0, 360, 20):
x = 10 * math.cos(math.radians(i))
y = 10 * math.sin(math.radians(i))
spl = math.degrees(math.atan2(y - 0, x - 0)) % 360
plt.plot([0, x], [0, y], label=str(i))
plt.legend()
plt.show()
Please notice we are getting slope angles for all lines between (0, 0) and (cos, sin) (See: Cartesian to Polar) for each 20 degrees.
Now we need a logic to understand if a line is vertical or horizontal by given slope angle:
Horizontal
I would say each line with slope angles between [160, 200] or bigger then 340 or smaller then 20 is horizontal.
if 160 < angle < 200 or 340 < angle or angle < 20
Better way:
if 160 < angle < 200 or not 20 < angle < 340
Vertical
I would say each line with slope angles between [60, 120] or [240, 300] is vertical.
if 60< angle < 120 or 240 < angle < 300.
Let's assign a limit variable as a threshold so we can change it as will:
for horizontal lines:
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 + limit):
for vertical lines:
if (90 - limit < spl < 90 + limit) or (270 - limit < spl < 270 + limit):
The code to check would be:
def check_the_line(slope, limit=10):
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 + limit):
return "h"
elif (90 - limit < spl < 90 + limit) or (270 - limit < spl < 270 + limit):
return "v"
return "o"
Let's validate:
import math
from matplotlib import pyplot as plt
fig, (ax1, ax2, ax3) = plt.subplots(3, 1)
limit = 10
def check_the_line(slope, limit=10):
if (not limit < spl <= 360 - limit) or (180 - limit <= spl < 180 + limit):
return "h"
elif (90 - limit < spl < 90 + limit) or (270 - limit < spl < 270 + limit):
return "v"
return "o"
for i in range(0, 360, 1):
x = 10 * math.cos(math.radians(i))
y = 10 * math.sin(math.radians(i))
spl = math.degrees(math.atan2(y, x)) % 360
ax1.plot([0, x], [0, y])
if check_the_line(spl, limit=limit) == "h":
ax2.plot([0, x], [0, y])
elif check_the_line(spl, limit=limit) == "v":
ax3.plot([0, x], [0, y])
ax1.set_title("All lines")
ax1.set_xlim([-10, 10])
ax1.set_ylim([-10, 10])
ax2.set_title("Horizontal Lines")
ax2.set_xlim([-10, 10])
ax2.set_ylim([-10, 10])
ax3.set_title("Vertical Lines")
ax3.set_xlim([-10, 10])
ax3.set_ylim([-10, 10])
plt.show()
As you know the coordinates of the endpoints, you could simply compute the slope of the line with
slope = (y2 - y1) / (x2 - x1)
If the slope is 0, then the line is horizontal, if it's infinity, then the line is vertical.
In practice, you'll rarely have slopes equal to 0 or infinity. So simply put a threshold like:
if abs(slope) < 1:
print("It's an horizontal line!")
elif abs(slope) > 100:
print("It's a vertical line!")
else:
print("It's... a line!")
One other simple solution, if you really care only for horizontal and vertical lines, is to compare x values, and y values:
if abs(x1 - x2) < 5:
print("It's a vertical line!")
elif abs(y1 - y2) < 5:
print("It's an horizontal line!")
else:
print("It's... a line!")
Edit: I added the absolute value to the slope comparisons.

Confused why this doesn't produce a straight line of slope 1 and angle 45

from matplotlib import pyplot as plt
import numpy as np
# Python program for slope of line
def slope(x1, y1, x2, y2):
return (float)(y2-y1)/(x2-x1)
midPoint = 400
tenPercentOfMidpoint = .10 * midPoint
x = np.linspace(midPoint - tenPercentOfMidpoint, midPoint + tenPercentOfMidpoint, 50)
m = np.empty(x.shape)
c = np.empty(x.shape)
m[(x>=midPoint)] = 1.0
m[(x<midPoint)] = 1.0
c[x<midPoint] = 0
c[x>=midPoint] = 0
y=m*x+c
lenOfx = len(x)
lenOfy = len(y)
s = slope(0, y[0], lenOfx, y[lenOfy - 1])
angle = np.rad2deg(np.arctan2(x[-1] - x[0], lenOfy - 0))
If I now print s
print(s)
the result is 1.6
If I print the angle
print(angle)
the result is 57.99
I want a line between midPoint - tenPercent and midPoint + tenPercent that has slope 1 and angle 45
I believe this is just a problem of plugging in things incorrectly. The points you are testing in your slope are (0, y[0]) == (0, 360.0) and (lenOfx, y[lenOfy - 1]) == (50, 440.0); these points are not on the line defined by y=m*x+c. I believe you instead want to pull the two endpoints of the segment:
>>> slope(x[0], y[0], x[-1], y[-1]) # (360.0, 360.0, 440.0, 440.0)
1.0
Similar problem for calculating the angle; you want to use the change in y and the change in x:
>>> np.rad2deg(np.arctan2(y[-1] - y[0], x[-1] - x[0]))
45.0
The number of coordinates (len) should not be relevant to the slope calculation.
Note that x and y are the same (x == y returns a vector of True).
For a line to have a slope of 1, the change in y should be same as change in x i.e. by definition of slope
I want a line between midPoint - tenPercent and midPoint + tenPercent that has slope 1 and angle 45
The closest thing to a line of slope 1 would be by changing x
x = np.linspace(midPoint - tenPercentOfMidpoint, midPoint + tenPercentOfMidpoint, int(2*tenPercentOfMidpoint))
or by changing tenPercentOfMidpoint to a number such that
2*tenPercentOfMidpoint=50 ## because you mentioned 50 in np.linspace
tenPercentOfMidpoint=25

Categories