Построение значений у дуги - PullRequest
2 голосов
/ 16 февраля 2020

Я пытаюсь построить сегмент круга (2D) как ar c в matplotlib. Я написал класс, который обеспечит математику для сегмента, такую ​​как длина аккорда, высота ar c et c. I wi sh для построения значений xy между (0,0) и (0, длина хорды).

В настоящее время я представляю значения X как numpy массив linspace (0, chordLength, 200). Я немного озадачен тем, как изобразить значения y как похожий массив linspace, чтобы я мог построить эти точки, используя matplotlib. Идея заключается в том, чтобы отобразить кривизну Земли между двумя точками известной длины ar c (расстояние по большому кругу). Я читал вокруг Sine Cosine et c, однако, за исключением использования формул фрезы cook ie для моих расчетов геометрии, я несколько растерялся относительно того, как применять его для получения моих значений 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()

Для контекста я sh буду использовать этот 'ar c' для добавления данных высот, вроде - https://link.ui.com/#. Я надеюсь смоделировать увеличенную кривизну на расстоянии, которую я могу использовать для грубого анализа прямой видимости.

Однако первым шагом является получение значений y.

1 Ответ

0 голосов
/ 18 февраля 2020

Вот окончательное решение, я не на 100% о математике и о том, как все это работает, но если кто-то борется с той же проблемой - надеюсь, это поможет.

Можно найти класс круга в оригинальном вопросе, расположенном ниже. Найдите прикрепленный окончательный код, который дает мне то, что я преследовал - моделирование кривизны Земли на графике на основе длины ar c (расстояние по большому кругу).

Большое спасибо всем, кто принял время, чтобы ответить мне и помочь мне на моем пути.

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()

Вот пример готового продукта -

https://i.gyazo.com/1377cdd9d7eefe5608bc4c1dd2b3964e.png

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...