Reputation: 368
I'm trying to return a count of points within specified segments of a circle. The following df contains points at various timescales. The circle centre is designated by refX
and refY
. I'm hoping to split the circle into 4 even segments but re-orientate the segments based on the value provided by rotation_angle
. Essentially, segment 1
is directly orientated by the rotation_angle
and the following segments (2-4)
go clockwise from this angle.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'Time' : [1,1,1,1,2,2,2,2],
'id' : ['A','B','C','D','A','B','C','D'],
'X' : [1,-1,-1,2,1,-1,-2,2],
'Y' : [-2,-2,2,2,2,-2,-2,2],
'refX' : [0,0,0,0,-1,-1,-1,-1],
'refY' : [0,0,0,0,1,1,1,1],
'rotation_angle' : [-135,-135,-135,-135,0,0,0,0]
})
def checkPoint(x, y, rotation_angle, refX, refY, radius = 5):
section_angle_start = [(i + rotation_angle - 45) for i in [0, 90, 180, 270, 360]]
Angle = np.arctan2(x-refX, y-refY) * 180 / np.pi
Angle = Angle % 360
for i in range(4):
if section_angle_start[i] < Angle < section_angle_start[i+1]:
break
else:
i = 0
return i+1
time = 1
tmp = []
result = []
for i, row in df.iterrows():
seg = checkPoint(row.X, row.Y, row.rotation_angle, row.refY, row.refX)
if row.Time == time:
tmp.append(seg)
else:
result.append([time]+[tmp.count(i) for i in [1,2,3,4]])
time += 1
tmp = []
tmp.append(seg)
result.append([time]+[tmp.count(i) for i in [1,2,3,4]])
result = pd.DataFrame(result, columns=['Time', 'Seg1', 'Seg2', 'Seg3', 'Seg4'])
print(result)
Intended Output:
Time Seg1 Seg2 Seg3 Seg4
0 1 1 1 1 1
1 2 0 2 2 0
Upvotes: 0
Views: 726
Reputation: 2285
You can check in which segment each point is, by determining the position and angle of the circle and axis. Note that axis refX,refY are 90deg rotated to xy axis. And the case points are on the axis is eliminated in this code.
# df is from your question...
def checkPoint(x, y, rotation_angle, refX, refY, radius = 5):
import sys
# check if is it inside circle
if (y-refY)**2 + (x-refX)**2 > radius**2:
print("outo of radius")
sys.exit()
section_angle_start = [(i + rotation_angle - 45) for i in [0, 90, 180, 270, 360]]
Angle = np.arctan2(x-refX, y-refY) * 180 / np.pi
Angle = Angle % 360
# adjust range
if Angle > section_angle_start[-1]:
Angle -= 360
elif Angle < section_angle_start[0]:
Angle += 360
for i in range(4):
if section_angle_start[i] < Angle < section_angle_start[i+1]:
break
else:
i = 0
return i+1 # found segment
time = 1
tmp = []
result = []
for i, row in df.iterrows():
seg = checkPoint(row.X, row.Y, row.rotation_angle, row.refX, row.refY)
if row.Time == time:
tmp.append(seg)
else:
result.append([time]+[tmp.count(i) for i in [1,2,3,4]])
time += 1
tmp = []
tmp.append(seg)
result.append([time]+[tmp.count(i) for i in [1,2,3,4]])
pd.DataFrame(result, columns=['Time', 'Seg1', 'Seg2', 'Seg3', 'Seg4'])
Upvotes: 1