got stationary wireframe sphere !
This commit is contained in:
parent
6b95683fcd
commit
95f71c3430
|
@ -88,7 +88,7 @@ if __name__=="__main__":
|
||||||
pygame.init()
|
pygame.init()
|
||||||
pygame.display.set_caption("Spinny")
|
pygame.display.set_caption("Spinny")
|
||||||
|
|
||||||
window = pygame.display.set_mode((600, 600))
|
window = pygame.display.set_mode((900, 900))
|
||||||
resolutionDownscaling = 2
|
resolutionDownscaling = 2
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ 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(2000,6000,-2500), "BoSLOO", 3, thisEarth)
|
sat = OrbitingBody(Point(config()["earthRadius"] * 1.5, 0, 0), Point(2000,6000,-2500), "BoSLOO", 3, thisEarth)
|
||||||
orbitlines = []
|
orbitlines = []
|
||||||
renderObjects = [thisEarth, sat, orbitlines]
|
renderObjects = [thisEarth, sat, orbitlines]
|
||||||
imageThread = threading.Thread()
|
imageThread = threading.Thread()
|
||||||
|
@ -110,7 +110,7 @@ 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, 5 * config()["earthRadius"]), thisEarth, renderObjects)
|
camera = Camera(window, Point(0, 0, 4 * 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()
|
||||||
|
|
50
renderer.py
50
renderer.py
|
@ -1,10 +1,17 @@
|
||||||
import numpy, pygame, math
|
import numpy, pygame, math
|
||||||
|
import pygame.freetype
|
||||||
|
|
||||||
class Point:
|
class Point:
|
||||||
"""Numpy 3-vec"""
|
"""Numpy 3-vec"""
|
||||||
def __init__(self, x, y, z):
|
def __init__(self, x, y, z):
|
||||||
self.vector = numpy.array([x, y, z])
|
self.vector = numpy.array([x, y, z])
|
||||||
|
|
||||||
|
def polar(self):
|
||||||
|
rho = math.sqrt(self.vector[0] ** 2 + self.vector[1] ** 2 + self.vector[2] ** 2)
|
||||||
|
theta = math.atan(self.vector[2]/self.vector[0])
|
||||||
|
phi = math.acos((self.vector[1])/(rho))
|
||||||
|
return [rho, theta, phi]
|
||||||
|
|
||||||
def magnitude(self):
|
def magnitude(self):
|
||||||
return numpy.linalg.norm(self.vector)
|
return numpy.linalg.norm(self.vector)
|
||||||
|
|
||||||
|
@ -79,6 +86,7 @@ class Camera:
|
||||||
|
|
||||||
def renderFrame(self):
|
def renderFrame(self):
|
||||||
"""generates a frame and draws it to the surface. Does not update screen; use pygame.display.flip()"""
|
"""generates a frame and draws it to the surface. Does not update screen; use pygame.display.flip()"""
|
||||||
|
font = pygame.freetype.SysFont("Comic Sans MS", 14)
|
||||||
winWidth, winHeight = self.surface.get_size()
|
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
|
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 = Point.subtract(self.target.location, self.location)
|
||||||
|
@ -88,12 +96,14 @@ class Camera:
|
||||||
#pygame uses 0,0 as the top left corner
|
#pygame uses 0,0 as the top left corner
|
||||||
for obj in self.objects:
|
for obj in self.objects:
|
||||||
if type(obj).__name__ == "OrbitingBody":
|
if type(obj).__name__ == "OrbitingBody":
|
||||||
|
sat = obj
|
||||||
lineToCamera = Line(obj.location, self.location)
|
lineToCamera = Line(obj.location, self.location)
|
||||||
intersectPoint = lineToCamera.intersectWithPlane(screenPlane)
|
intersectPoint = lineToCamera.intersectWithPlane(screenPlane)
|
||||||
if intersectPoint is not None:
|
if intersectPoint is not None:
|
||||||
intersectPoint = Point.add(intersectPoint, Point(int(winWidth/2), int(winHeight/2), 0))
|
intersectPoint = Point.add(intersectPoint, Point(int(winWidth/2), int(winHeight/2), 0))
|
||||||
pygame.draw.circle(screenSurface, (255,255,150), (int(intersectPoint.vector[0]), int(intersectPoint.vector[1])), obj.displaySize)
|
pygame.draw.circle(screenSurface, (255,255,150), (int(intersectPoint.vector[0]), int(intersectPoint.vector[1])), obj.displaySize)
|
||||||
elif type(obj).__name__ == "Planet":
|
elif type(obj).__name__ == "Planet":
|
||||||
|
target = obj
|
||||||
lineToCamera = Line(obj.location, self.location)
|
lineToCamera = Line(obj.location, self.location)
|
||||||
intersectPoint = lineToCamera.intersectWithPlane(screenPlane)
|
intersectPoint = lineToCamera.intersectWithPlane(screenPlane)
|
||||||
if intersectPoint is not None:
|
if intersectPoint is not None:
|
||||||
|
@ -110,8 +120,17 @@ class Camera:
|
||||||
|
|
||||||
|
|
||||||
screenSurface = pygame.transform.flip(screenSurface, False, True)
|
screenSurface = pygame.transform.flip(screenSurface, False, True)
|
||||||
|
|
||||||
|
#generate text
|
||||||
|
rho, theta, phi = sat.location.polar()
|
||||||
|
theta = math.degrees(theta)
|
||||||
|
phi = math.degrees(phi)
|
||||||
|
|
||||||
|
#textSurface, rect = font.render(f"Speed: {round(sat.velocity.magnitude())} m/s \nAltitude: {round(rho - target.radius)} m", False, (255,255,255))
|
||||||
|
font.render_to(screenSurface, (0,0), f"Speed: {round(sat.velocity.magnitude())} m/s \nAltitude: {round(rho - target.radius)} m", (255,255,255))
|
||||||
self.surface.blit(screenSurface, (0,0))
|
self.surface.blit(screenSurface, (0,0))
|
||||||
|
|
||||||
|
|
||||||
def renderImage(self, sat:"OrbitingBody"):
|
def renderImage(self, sat:"OrbitingBody"):
|
||||||
"""generates a single image and saves it to disk"""
|
"""generates a single image and saves it to disk"""
|
||||||
frozenSat = sat.location
|
frozenSat = sat.location
|
||||||
|
@ -126,8 +145,7 @@ class Camera:
|
||||||
|
|
||||||
satDistance = -1
|
satDistance = -1
|
||||||
|
|
||||||
#DEBUG
|
curveCoeff = 1.1
|
||||||
minlat = 1
|
|
||||||
|
|
||||||
for column in range(0, winWidth):
|
for column in range(0, winWidth):
|
||||||
for row in range(0, winHeight):
|
for row in range(0, winHeight):
|
||||||
|
@ -142,22 +160,34 @@ class Camera:
|
||||||
|
|
||||||
if self.target.location.distanceFromLine(worldLine) < self.target.radius:
|
if self.target.location.distanceFromLine(worldLine) < self.target.radius:
|
||||||
epsilon = 0.1
|
epsilon = 0.1
|
||||||
yPrime = (row + screenPlaneOrigin.vector[1]) * (self.location.vector[2] / winDistance)
|
yPrime = min([abs((row + screenPlaneOrigin.vector[1]) * (self.location.vector[2] / winDistance)), self.target.radius])
|
||||||
|
yPrimeCurve = yPrime / (self.target.radius * curveCoeff)
|
||||||
xPrime = min([abs((column + screenPlaneOrigin.vector[0]) * (self.location.vector[2] / winDistance)), self.target.radius])
|
xPrime = min([abs((column + screenPlaneOrigin.vector[0]) * (self.location.vector[2] / winDistance)), self.target.radius])
|
||||||
|
xPrimeCurve = xPrime / (self.target.radius * curveCoeff)
|
||||||
|
#treat yPrime like it's further from zero than it really is based on xPrime, and vice versa
|
||||||
|
yPrime /= math.sin(math.acos(xPrimeCurve))
|
||||||
|
xPrime /= math.sin(math.acos(yPrimeCurve))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lat = math.modf((math.acos(yPrime / self.target.radius) / (3.141592/12.0)))[0] * math.sin(math.acos(xPrime / self.target.radius))
|
lat = math.modf((math.acos(yPrime / self.target.radius) / (3.141592/12.0)))[0] #pi/12 = 15 degrees
|
||||||
except:
|
except:
|
||||||
screenSurface.set_at((column, row), (20,20,20))
|
screenSurface.set_at((column, row), (20,20,20))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if lat < minlat:
|
try:
|
||||||
minlat = lat
|
long = math.modf((math.acos(xPrime / self.target.radius) / (3.141592/6.0)))[0] #pi/6 = 30 degrees
|
||||||
|
except:
|
||||||
if -epsilon < lat < epsilon:
|
|
||||||
screenSurface.set_at((column, row), (200,200,200))
|
|
||||||
else:
|
|
||||||
screenSurface.set_at((column, row), (20,20,20))
|
screenSurface.set_at((column, row), (20,20,20))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if -epsilon < lat < epsilon or -epsilon < long < epsilon:
|
||||||
|
screenSurface.set_at((column, row), (180,180,180))
|
||||||
|
elif -epsilon < lat < epsilon and -epsilon < long < epsilon:
|
||||||
|
screenSurface.set_at((column, row), (255,255,255))
|
||||||
|
else:
|
||||||
|
screenSurface.set_at((column, row), (50,50,50))
|
||||||
|
|
||||||
|
#check if satellite is behind or in front of planet (or unobscured)
|
||||||
if screenSurface.get_at(satPixel) == (0,0,0):
|
if screenSurface.get_at(satPixel) == (0,0,0):
|
||||||
circleBorder = 0
|
circleBorder = 0
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue