Python有没有一种方法可以识别角度的方向性?

2024-10-08 21:21:08 发布

您现在位置:Python中文网/ 问答频道 /正文

下图显示了一种所谓的泪滴状DNA分子。对我来说,这个DNA弯曲角度的分布是非常有趣的。红色显示由skimage.morphology.skeletonize生成的跟踪。 在我的程序中,跟踪被表示为一个numpy数组:numpy数组中的每个条目都是一个float64元组,对应于图像中跟踪点的x和y坐标。因此,如果我应用np.diff(trace, axis=0),我会得到我想要在向量中分析的片段

问题:现在,我想知道如何计算两个后续段之间的角度。但是,我现在不知道角度是顺时针还是逆时针。例如,在某一点上,DNA向左弯曲,因此那里的角度与DNA向右弯曲时测得的角度不同,这通常是正确的。解决这个问题的方法是什么

到目前为止我的想法: 我想对每个线段进行插值,然后检查下一个线段是否位于插值线的下方或上方,表示顺时针与逆时针的角度。但这似乎很难实现,因为我是一个初学者,任何输入都将非常感谢The Teardrop Molecule. I want to measure the angles between subsequent segments of the trace in red.


Tags: 程序numpy数组分子dna插值角度红色
1条回答
网友
1楼 · 发布于 2024-10-08 21:21:08

我认为交叉积np.cross将在这里帮助您。对于一个简单的三角形,先逆时针旋转,然后顺时针旋转,看起来可能是这样的(可以优化,为了清晰起见,让它保持更长的距离)。角度输出是矢量之间的夹角,方向遵循右手规则:编辑:添加方向变化的曲线,添加图形(逆时针方向的注释):

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path

def drangl(vsgi, vsgi1):
    '''sin(theta)=|axb|/(|a||b|)'''
    return np.arcsin(np.cross(vsgi, vsgi1)/np.linalg.norm(vsgi)/np.linalg.norm(vsgi1))

print('going around the traingle counter-clockwise and clockwise:\n')

trace = np.array([(0.,0.), (10.,-1.), (5.,10.), (0.,0.)])
vsegs = np.diff(trace, axis=0)

for iv in [0,1,-1]: # counter-clockwise
    print(f'ctr-cl: {iv:d} {drangl(vsegs[iv], vsegs[iv+1]):2.2f}')
for iv in [-1,1,0]: # clockwise
    print(f'cw: {iv:d} {drangl(vsegs[iv], vsegs[iv+1]):2.2f}')
    
print('\nnow with direction change in the path:\n')

trace = np.array([(0.,0.), (10.,-1.), (9., 5.), (12., 5.), (5.,10.), (0.,0.)])
vsegs = np.diff(trace, axis=0)
    
for iv in [0,1,2,3,-1]: # counter-clockwise
    print(f'ctr-cl: {iv:d} {drangl(vsegs[iv], vsegs[iv+1]):2.2f}')
for iv in [-1,3,2,1,0]: # clockwise
    print(f'cw: {iv:d} {drangl(vsegs[iv], vsegs[iv+1]):2.2f}')
    
codes = [
    Path.MOVETO,
    Path.LINETO,
    Path.LINETO,
    Path.LINETO,
    Path.LINETO,
    Path.CLOSEPOLY,
]

path = Path(trace, codes)
fig, ax = plt.subplots()
patch = patches.PathPatch(path, facecolor='white', lw=2)
ax.add_patch(patch)
ax.set_xlim(-1, 13)
ax.set_ylim(-2, 11)
ax.annotate('turns right', xy=(9, 5), xytext=(5, 5),
            arrowprops=dict(facecolor='black', shrink=0.05),
            )
ax.annotate('turns left', xy=(12, 5), xytext=(10, 10),
            arrowprops=dict(facecolor='black', shrink=0.05),
            )
plt.show()

产生

逆时针和顺时针绕列车运行:

ctr-cl: 0 1.04
ctr-cl: 1 0.89
ctr-cl: -1 1.21
cw: -1 1.21
cw: 1 0.89
cw: 0 1.04

now with direction change in the path:

ctr-cl: 0 1.31
ctr-cl: 1 -1.41
ctr-cl: 2 0.62
ctr-cl: 3 1.41
ctr-cl: -1 1.21
cw: -1 1.21
cw: 3 1.41
cw: 2 0.62
cw: 1 -1.41
cw: 0 1.31

enter image description here

符号更改现在指示曲线更改方向的位置

相关问题 更多 >

    热门问题