python-3.x - 绘制圆弧的 y 值
问题描述
我正在尝试在 matplotlib 中将圆(2D)的段绘制为弧。我写了一个类,它将提供段的数学,如弦长、弧高等。我希望绘制 (0,0) 和 (0, 弦长) 之间的 xy 值。
我目前将 X 值表示为 numpy linspace 数组(0,chordLength,200)。对于如何将 y 值绘制为类似的 linspace 数组以便我可以使用 matplotlib 绘制这些点,我有点难过。这背后的想法是显示已知弧长(大圆距离)的两点之间的地球曲率。我一直在阅读正弦余弦等,但是除了使用千篇一律的几何计算公式之外,我对如何应用它来获得我的 y 值有些迷茫。
一、圈类
import numpy as np
class Circle:
def __init__(self,radiusOfCircle,lengthOfArc):
self.radius = radiusOfCircle
self.circumference = 2 * np.pi * self.radius
self.diameter = self.radius * 2
self.arcLength = lengthOfArc
self.degrees = self.calcDegrees()
self.radians = self.calcRadians()
self.chordLength = self.calcChordLength()
self.sagitta = self.calcSagitta()
self.segmentArea = self.calcSegmentArea()
self.arcHeight = self.calcArcHeight()
#Setters and getters for the Circle class (TODO: setters)
def getRadius(self):
return self.radius
def getCircumference(self):
return self.circumference
def getDiameter(self):
return self.diameter
def getArcLength(self):
return self.arcLength
def getRadians(self):
return self.radians
def getDegrees(self):
return self.degrees
def getChordLength(self):
return self.chordLength
def getSagitta(self):
return self.sagitta
def getSegmentArea(self):
return self.segmentArea
def getArcHeight(self):
return self.arcHeight
#Define Circle class methods
#Calculate the central angle, in degrees, by using the arcLength
def calcDegrees(self):
self.degrees = (self.arcLength / (np.pi * self.diameter)) * 360 #Gives angle in degrees at centre of the circle between the two points (beginning and end points of arcLength)
return self.degrees
#Calculate the central angle in radians, between two points on the circle
def calcRadians(self):#Where theta is the angle between both points at the centre of the circle
self.radians = np.radians(self.degrees) # Convert degrees to radians to work with ChordLength formula
return self.radians
#Returns the chord lengths of the arc, taking theta (angle in radians) as it's argument
#The chord is the horizontal line which separates the arc segment from the rest of the circle
def calcChordLength(self):
self.chordLength = 2*self.radius*np.sin(self.radians/2) #formula works for theta (radians) only, not degrees #confirmed using http://www.ambrsoft.com/TrigoCalc/Sphere/Arc_.htm
return self.chordLength
#Calculates the length of arc, taking theta (angle in radians) as its argument.
def calcArcLength(self):
self.arcLength = (self.degrees/360)*self.diameter*np.pi #confirmed using http://www.ambrsoft.com/TrigoCalc/Sphere/Arc_.htm
return self.arcLength
#Calculates the sagitta of the arc segment. The sagitta is the horizontal line which extends from the bottom
#of the circle to the chord of the segment
def calcSagitta(self):
self.sagitta = self.radius - (np.sqrt((self.radius**2)-((self.chordLength/2)**2))) #Confirmed correct against online calculator https://www.liutaiomottola.com/formulae/sag.htm
return self.sagitta
#Calculates the area of the circular segment/arc).
def calcSegmentArea(self):
self.segmentArea = (self.radians - np.sin(self.radians) / 2) * self.radius**2
return self.segmentArea
#Calculate the height of the arc
#Radius - sagitta of the segment
def calcArcHeight(self):
self.arcHeight = self.radius - self.sagitta
return self.arcHeight
我在主程序上的进展还不是很远,因为我打算做的首要任务之一是创建 y 值。这是我到目前为止所拥有的 -
from circle import Circle
import numpy as np
import matplotlib.pyplot as plt
def main():
#define centre point
#Circle(radius,arc length)
c1 = Circle(3440.065,35) #Nautical miles radius with 35Nm arc length
chordLength = c1.getChordLength()
arcHeight = c1.getArcHeight()
centerX = chordLength/2
centerY = 0
if __name__ == "__main__":
main()
对于上下文,我希望使用此“弧”将高程数据添加到,类似于 - https://link.ui.com/#。我希望模拟随距离增加的曲率,我可以将其用于粗略的视线分析。
但是,第一步是获取 y 值。
解决方案
这是最终的解决方案,我不是 100% 了解数学以及它是如何工作的,但如果有人在同一个问题上苦苦挣扎 - 我希望这会有所帮助。
circle 类可以在下面的原始问题中找到。Find 附加了最终代码,它为我提供了我所追求的东西 - 根据弧长(大圆距离)在图表上模拟地球的曲率。
非常感谢所有花时间回答我并帮助我的人。
from circle import Circle
import numpy as np
import matplotlib.pyplot as plt
def calcStartAngle(startY,centreY,startX,centreX):
startAngle = np.arctan2(startY-centreY, startX-centreX)
return startAngle
def calcEndAngle(endY,centreY,endX,centreX):
endAngle = np.arctan2(endY-centreY, endX-centreX)
return endAngle
def main():
distance = 200
radius = 3440.065
#create circle object
c1 = Circle(radius,distance)
angle = c1.getDegrees()
xc = c1.getXc()
yc = c1.getYc()
#set start and end points
x1,y1 = 0,0
x2,y2 = distance,0
#get start and end angles
startAngle = calcStartAngle(y1,yc,x1,xc)
endAngle = calcEndAngle(y2,yc,x2,xc)
angleList = np.linspace(startAngle,endAngle,distance)
x_values = np.linspace(x1,x2,distance)
y_valuesList = []
for i in range(len(x_values)):
y = radius*np.sin(angleList[i]) - c1.getArcHeight()
y_valuesList.append(y)
#Create numpy array to hold y values
y_values = np.array(y_valuesList)
plt.ylim(0,50)
plt.plot(x_values,y_values)
plt.show()
if __name__ == "__main__":
main()
这是成品的一个例子 -
推荐阅读
- c# - Winforms - C# 任务栏进度指示器 (Windows 10)
- android - 如何检查协程是否使用相同的上下文?
- node.js - 如何解决 res.status 不是函数?
- jenkins - 向存在的 html 文件发送电子邮件通知
- branch.io - 与 Facebook 广告合作伙伴在 Branch.io 上连接订阅和开始试用
- mysql - 计算相对于特定值的 zscore
- tensorflow - 无法添加第四个卷积层
- javascript - Javascript Bookmarklet:如何在复制到剪贴板之前从 document.title 中删除某些文本?
- python - 限制 tkinter 中的输入,以便可以输入价格,按键将数字放在百分之一美元中,小数是固定的
- android - Room 数据库使用协程异步返回 Null