사전에 약간의 면책 조항을 보았습니다. 나는 천문학이나 그 문제에 대한 정확한 과학 (IT조차도)을 연구 한 적이 없으므로 자체 교육을 통해이 격차를 메우려 고합니다. 천문학은 저의주의를 끌었던 분야 중 하나이며 자기 교육에 대한 나의 생각은 응용 접근법에 대한 머리입니다. 요컨대, 시간 / 분위기가있을 때 우연히 작업하는 궤도 시뮬레이션 모델입니다. 저의 주요 목표는 모션으로 완벽한 태양계를 만들고 다른 행성에 우주선 발사를 계획하는 능력입니다.
언제든지이 프로젝트를 자유롭게 선택하고 즐겁게 실험 할 수 있습니다!
최신 정보!!! (11 월)
- 속도는 이제 적절한 deltaV이며 추가 모션을 제공하면 속도의 합 벡터가 계산됩니다.
- 모션에서 모든 소스의 중력 벡터를 검사하고 충돌을 검사 할 때마다 단위 오브젝트에 원하는 수의 정적 오브젝트를 배치 할 수 있습니다.
- 계산 성능을 크게 향상
- matplotlib에서 대화식 모드를 설명하기위한 수정. 이것이 ipython의 기본 옵션 인 것 같습니다. 일반 python3에는 해당 명령문이 명시 적으로 필요합니다.
기본적으로 이제 지구 표면에서 우주선을 "발사"하고 giveMotion ()을 통해 deltaV 벡터 보정을 수행하여 달에 대한 임무를 그릴 수 있습니다. 다음으로 우주선이 중력 지원 기동을 시도하는 동안 달 궤도를 도는 지구와 같은 동시 모션을 가능하게하는 전역 시간 변수를 구현하려고합니다.
개선에 대한 의견과 제안은 언제나 환영합니다!
matplotlib 라이브러리를 사용하여 Python3에서 완료
import matplotlib.pyplot as plt
import math
plt.ion()
G = 6.673e-11 # gravity constant
gridArea = [0, 200, 0, 200] # margins of the coordinate grid
gridScale = 1000000 # 1 unit of grid equals 1000000m or 1000km
plt.clf() # clear plot area
plt.axis(gridArea) # create new coordinate grid
plt.grid(b="on") # place grid
class Object:
_instances = []
def __init__(self, name, position, radius, mass):
self.name = name
self.position = position
self.radius = radius # in grid values
self.mass = mass
self.placeObject()
self.velocity = 0
Object._instances.append(self)
def placeObject(self):
drawObject = plt.Circle(self.position, radius=self.radius, fill=False, color="black")
plt.gca().add_patch(drawObject)
plt.show()
def giveMotion(self, deltaV, motionDirection, time):
if self.velocity != 0:
x_comp = math.sin(math.radians(self.motionDirection))*self.velocity
y_comp = math.cos(math.radians(self.motionDirection))*self.velocity
x_comp += math.sin(math.radians(motionDirection))*deltaV
y_comp += math.cos(math.radians(motionDirection))*deltaV
self.velocity = math.sqrt((x_comp**2)+(y_comp**2))
if x_comp > 0 and y_comp > 0: # calculate degrees depending on the coordinate quadrant
self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity)) # update motion direction
elif x_comp > 0 and y_comp < 0:
self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 90
elif x_comp < 0 and y_comp < 0:
self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity)) + 180
else:
self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 270
else:
self.velocity = self.velocity + deltaV # in m/s
self.motionDirection = motionDirection # degrees
self.time = time # in seconds
self.vectorUpdate()
def vectorUpdate(self):
self.placeObject()
data = []
for t in range(self.time):
motionForce = self.mass * self.velocity # F = m * v
x_net = 0
y_net = 0
for x in [y for y in Object._instances if y is not self]:
distance = math.sqrt(((self.position[0]-x.position[0])**2) +
(self.position[1]-x.position[1])**2)
gravityForce = G*(self.mass * x.mass)/((distance*gridScale)**2)
x_pos = self.position[0] - x.position[0]
y_pos = self.position[1] - x.position[1]
if x_pos <= 0 and y_pos > 0: # calculate degrees depending on the coordinate quadrant
gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+90
elif x_pos > 0 and y_pos >= 0:
gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))+180
elif x_pos >= 0 and y_pos < 0:
gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+270
else:
gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))
x_gF = gravityForce * math.sin(math.radians(gravityDirection)) # x component of vector
y_gF = gravityForce * math.cos(math.radians(gravityDirection)) # y component of vector
x_net += x_gF
y_net += y_gF
x_mF = motionForce * math.sin(math.radians(self.motionDirection))
y_mF = motionForce * math.cos(math.radians(self.motionDirection))
x_net += x_mF
y_net += y_mF
netForce = math.sqrt((x_net**2)+(y_net**2))
if x_net > 0 and y_net > 0: # calculate degrees depending on the coordinate quadrant
self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce)) # update motion direction
elif x_net > 0 and y_net < 0:
self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 90
elif x_net < 0 and y_net < 0:
self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce)) + 180
else:
self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 270
self.velocity = netForce/self.mass # update velocity
traveled = self.velocity/gridScale # grid distance traveled per 1 sec
self.position = (self.position[0] + math.sin(math.radians(self.motionDirection))*traveled,
self.position[1] + math.cos(math.radians(self.motionDirection))*traveled) # update pos
data.append([self.position[0], self.position[1]])
collision = 0
for x in [y for y in Object._instances if y is not self]:
if (self.position[0] - x.position[0])**2 + (self.position[1] - x.position[1])**2 <= x.radius**2:
collision = 1
break
if collision != 0:
print("Collision!")
break
plt.plot([x[0] for x in data], [x[1] for x in data])
Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(100.0, 100.0), radius=1.737, mass = 7.347e22) # position not to real scale
Craft = Object(name="SpaceCraft", position=(49.0, 40.0), radius=1, mass=1.0e4)
Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)
Craft.giveMotion(deltaV=2000.0, motionDirection=90, time=60000)
plt.show(block=True)
작동 원리
그것은 모두 두 가지로 요약됩니다.
Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)
그리드의 위치 매개 변수 (기본적으로 1 개의 그리드 단위는 1000km이지만 변경 될 수 있음), 그리드 단위의 반경 및 kg 단위의 질량 과 같은 객체 생성 .- 객체에 deltaV를 제공하는
Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)
것은 분명히Craft = Object(...)
이전 시점에서 언급 한 것처럼 처음부터 생성 해야 합니다. 여기의 매개 변수는deltaV
m / s입니다 (현재 가속은 순간적입니다),motionDirection
deltaV의 방향은 도입니다 (현재 위치에서 물체 주위의 360도 원을 상상하므로 방향은 해당 원의 점입니다). 그리고 마지막으로 매개 변수time
는 몇 초입니다 객체의 deltaV 푸시 궤적이 모니터링 된 후. 이후giveMotion()
의 이전 위치에서 시작합니다giveMotion()
.
질문 :
- 이것이 궤도를 계산하는 유효한 알고리즘입니까?
- 눈에 띄는 개선점은 무엇입니까?
- 매 초마다 벡터와 위치를 다시 계산할 필요가 없기 때문에 계산을 최적화하는 "timeScale"변수를 고려했습니다. 구현 방법에 대한 생각이나 일반적으로 좋은 생각입니까? (정확도의 손실 대 성능의 향상)
기본적으로 내 목표는 주제에 대한 토론을 시작하고 주제가 어디에서 나오는지 확인하는 것입니다. 그리고 가능하다면 새롭고 흥미로운 것을 배우십시오.
자유롭게 실험하십시오!
다음을 사용하십시오.
Earth = Object(name="Earth", position=(50.0, 100.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(434.0, 100.0), radius=1.737, mass = 7.347e22)
Craft = Object(name="SpaceCraft", position=(43.0, 100.0), radius=1, mass=1.0e4)
Craft.giveMotion(deltaV=10575.0, motionDirection=180, time=322000)
Craft.giveMotion(deltaV=400.0, motionDirection=180, time=50000)
지구 궤도에서 1 회, 달 궤도에서 1 회 후진으로 2 회의 화상으로 안정적인 달 궤도를 달성했습니다. 이것들은 이론적으로 기대되는 값에 가깝습니까?
제안 된 운동 : 3 번의 화상을 입으십시오-지구 표면에서 안정된 지구 궤도, 달에 도달하기 위해 점진적인 화상, 달 주위의 궤도를 안정시키기 위해 역행 화상. 그런 다음 deltaV를 최소화하십시오.
참고 : python3 구문에 익숙하지 않은 사람들을 위해 광범위한 주석으로 코드를 업데이트 할 계획입니다.