added renderImage to camera, to save a representative image of system at any point to disk
takes a long time oops
This commit is contained in:
parent
61562a0bd4
commit
fb222b6dea
13
OrbitSim.py
13
OrbitSim.py
|
@ -1,4 +1,4 @@
|
||||||
import os, json, numpy, pygame, time
|
import os, json, numpy, pygame, time, threading
|
||||||
from renderer import *
|
from renderer import *
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
|
@ -97,9 +97,11 @@ if __name__=="__main__":
|
||||||
running = True
|
running = True
|
||||||
display = False
|
display = False
|
||||||
thisEarth = deepcopy(Planet.Earth)
|
thisEarth = deepcopy(Planet.Earth)
|
||||||
sat = OrbitingBody(Point(config()["earthRadius"] * 1.1, 0, 0), Point(0,6000,-6500), "BoSLOO", 3, thisEarth)
|
sat = OrbitingBody(Point(config()["earthRadius"] * 1.1, 0, 0), Point(0,1000,-8500), "BoSLOO", 3, thisEarth)
|
||||||
orbitlines = []
|
orbitlines = []
|
||||||
renderObjects = [thisEarth, sat, orbitlines]
|
renderObjects = [thisEarth, sat, orbitlines]
|
||||||
|
imageThread = threading.Thread()
|
||||||
|
|
||||||
|
|
||||||
while running:
|
while running:
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
|
@ -108,16 +110,19 @@ if __name__=="__main__":
|
||||||
elif event.type == pygame.MOUSEBUTTONDOWN:
|
elif event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
if not display:
|
if not display:
|
||||||
display = True
|
display = True
|
||||||
camera = Camera(window, Point(0, 0, 3 * config()["earthRadius"]), thisEarth, renderObjects)
|
camera = Camera(window, Point(0, 0, 8 * config()["earthRadius"]), thisEarth, renderObjects)
|
||||||
pygame.draw.circle(window, (255,255,255), pygame.mouse.get_pos(), 100)
|
pygame.draw.circle(window, (255,255,255), pygame.mouse.get_pos(), 100)
|
||||||
camera.renderFrame()
|
camera.renderFrame()
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
else:
|
else:
|
||||||
|
if not imageThread.is_alive():
|
||||||
|
imageThread = threading.Thread(target=camera.renderImage, args=(sat,))
|
||||||
|
imageThread.start()
|
||||||
display = False
|
display = False
|
||||||
window.fill((0,0,0))
|
window.fill((0,0,0))
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
if display:
|
if display:
|
||||||
deltaTime = frameTime * config()["timeScale"]
|
deltaTime = frameTime * config()["timeScale"]
|
||||||
physicsUpdate(renderObjects, orbitlines, deltaTime)
|
physicsUpdate(renderObjects, orbitlines, deltaTime)
|
||||||
camera.renderFrame()
|
camera.renderFrame()
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
42
renderer.py
42
renderer.py
|
@ -12,9 +12,12 @@ class Point:
|
||||||
self.vector = self.vector/self.magnitude()
|
self.vector = self.vector/self.magnitude()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def distanceFrom(self, otherPoint:"Point"):
|
def distanceFromPoint(self, otherPoint:"Point"):
|
||||||
return numpy.linalg.norm(self.vector - otherPoint.vector)
|
return numpy.linalg.norm(self.vector - otherPoint.vector)
|
||||||
|
|
||||||
|
def distanceFromLine(self, line:"Line"):
|
||||||
|
return numpy.linalg.norm(numpy.cross(line.p2.vector - line.p1.vector, self.vector - line.p1.vector)/numpy.linalg.norm(line.p2.vector - line.p1.vector))
|
||||||
|
|
||||||
def add(p1, p2):
|
def add(p1, p2):
|
||||||
sum = numpy.add(p1.vector, p2.vector)
|
sum = numpy.add(p1.vector, p2.vector)
|
||||||
return Point(sum[0], sum[1], sum[2])
|
return Point(sum[0], sum[1], sum[2])
|
||||||
|
@ -108,6 +111,43 @@ class Camera:
|
||||||
|
|
||||||
screenSurface = pygame.transform.flip(screenSurface, False, True)
|
screenSurface = pygame.transform.flip(screenSurface, False, True)
|
||||||
self.surface.blit(screenSurface, (0,0))
|
self.surface.blit(screenSurface, (0,0))
|
||||||
|
|
||||||
|
def renderImage(self, sat:"OrbitingBody"):
|
||||||
|
"""generates a single image and saves it to disk"""
|
||||||
|
frozenSat = sat.location
|
||||||
|
winWidth, winHeight = self.surface.get_size()
|
||||||
|
winDistance = winWidth * numpy.cos(numpy.radians(self.hFOV)/2) / 2 #distance for a virtual screen to exist in-space to give the correct FOV
|
||||||
|
vecToCenter = Point.subtract(self.target.location, self.location)
|
||||||
|
vecToCenter.normalize()
|
||||||
|
screenPlane = Plane(Point.add(self.location, Point.scalarMult(vecToCenter, winDistance)), vecToCenter)
|
||||||
|
screenPlaneOrigin = Point.subtract(screenPlane.point, Point(int(winWidth/2), int(winHeight/2), 0))
|
||||||
|
screenSurface = pygame.Surface((winWidth, winHeight))
|
||||||
|
#pygame uses 0,0 as the top left corner
|
||||||
|
|
||||||
|
satDistance = -1
|
||||||
|
for column in range(0, winWidth):
|
||||||
|
for row in range(0, winHeight):
|
||||||
|
#get line in world going through this pixel
|
||||||
|
worldLine = Line(self.location, Point.add(screenPlaneOrigin, Point(column, row, 0)))
|
||||||
|
#compare distance from center of planet to radius of planet to determine intersection
|
||||||
|
if self.target.location.distanceFromLine(worldLine) < self.target.radius:
|
||||||
|
screenSurface.set_at((column, row), (100,255,100))
|
||||||
|
|
||||||
|
dist = frozenSat.distanceFromLine(worldLine)
|
||||||
|
if satDistance < 0 or dist < satDistance:
|
||||||
|
satDistance = dist
|
||||||
|
satPixel = (column, row)
|
||||||
|
|
||||||
|
if screenSurface.get_at(satPixel) == (0,0,0):
|
||||||
|
circleBorder = 0
|
||||||
|
else:
|
||||||
|
if self.location.distanceFromPoint(frozenSat) > self.location.distanceFromPoint(self.target.location):
|
||||||
|
circleBorder = 2
|
||||||
|
else:
|
||||||
|
circleBorder = 0
|
||||||
|
pygame.draw.circle(screenSurface, (230, 227, 64), satPixel, 4, width = circleBorder)
|
||||||
|
screenSurface = pygame.transform.flip(screenSurface, False, True)
|
||||||
|
pygame.image.save(screenSurface, "test.png")
|
||||||
|
|
||||||
|
|
||||||
#for row in range(int(-winHeight/2), int(winHeight/2)):
|
#for row in range(int(-winHeight/2), int(winHeight/2)):
|
||||||
|
|
Loading…
Reference in a new issue