【问题标题】:Plotting y values of an arc绘制圆弧的 y 值
【发布时间】:2020-02-16 13:38:26
【问题描述】:

我正在尝试在 matplotlib 中将圆(2D)的线段绘制为弧线。我写了一个类,它将提供段的数学,例如弦长、弧高等。我希望绘制 (0,0) 和 (0, 弦长) 之间的 x y 值。

我目前将 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 值。

【问题讨论】:

  • 我不明白你的意思:我希望绘制 (0,0) 和 (0, 弦长) 之间的 x y 值
  • 基本上我希望弧的起点在左侧,从 0、0 开始,弧的上升和下降类似于地球的曲率,如此处生成的图表所示- link.ui.com/#注意弧的高度随着距离的增加而增加。
  • 我在那个网站上没有看到弧线。您能否提供一张图片或一些说明来查看这样的弧线?
  • i.gyazo.com/322c0bfb18693854c66afe2446f7fe3f.png 希望有效,我指的图表位于屏幕底部,两点之间的距离越近,“曲线”越小,距离越远更明显的是。我最终想绘制单个点,因为我将沿这些点分层高程数据以进行视线分析。
  • 如果您回答自己的问题,请不要更改问题,而是将其作为答案发布。见stackoverflow.com/help/self-answer

标签: python-3.x numpy matplotlib math


【解决方案1】:

这是最终的解决方案,我不是 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()

这是成品的例子-

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多