Add files via upload
This commit is contained in:
commit
2c643765d0
110
main.py
Normal file
110
main.py
Normal file
@ -0,0 +1,110 @@
|
||||
from objects import *
|
||||
from useful import *
|
||||
|
||||
from threading import Thread
|
||||
import pygame
|
||||
|
||||
def main():
|
||||
try:
|
||||
print("Initializing...")
|
||||
data.multithreading = settings.useMultithreading
|
||||
data.running = True
|
||||
pygame.init()
|
||||
pygame.display.set_mode(settings.resolution)
|
||||
data.display = pygame.display.get_surface()
|
||||
data.pixelScale = int(pow(2, settings.maxPixelScale - 1))
|
||||
|
||||
if settings.useMultithreading: beginMultithreading()
|
||||
|
||||
print("Ready")
|
||||
|
||||
minPixelScale = int(pow(2, settings.minPixelScale - 1))
|
||||
while data.running and data.pixelScale >= minPixelScale:
|
||||
render()
|
||||
if not data.multithreading: pygame.display.update()
|
||||
getInputs()
|
||||
data.pixelScale /= 2
|
||||
|
||||
data.multithreading = False
|
||||
pygame.display.update()
|
||||
while data.running:
|
||||
getInputs()
|
||||
finally:
|
||||
print("Closing...")
|
||||
if settings.useMultithreading: endMultithreading()
|
||||
pygame.quit()
|
||||
|
||||
# begins any threads required for multithreading
|
||||
def beginMultithreading():
|
||||
print("Beginning multithreading")
|
||||
data.monitor = Thread(target=m_Monitor)
|
||||
data.monitor.start()
|
||||
|
||||
# kills all threads other than the main thread
|
||||
def endMultithreading():
|
||||
print("Ending multithreading")
|
||||
data.multithreading = False
|
||||
data.monitor.join()
|
||||
|
||||
# a monitor to constantly update the screen.
|
||||
# only used in multithreading.
|
||||
def m_Monitor():
|
||||
while data.multithreading:
|
||||
pygame.display.update()
|
||||
|
||||
# gets pygame inputs
|
||||
def getInputs():
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
data.running = False
|
||||
return
|
||||
|
||||
# renders a screen of fractal
|
||||
def render():
|
||||
for y in range(int(settings.resolution[1] / data.pixelScale)):
|
||||
if data.multithreading:
|
||||
pygame.draw.rect(data.display, (0, 0, 0), (0, y * data.pixelScale, settings.resolution[0], data.pixelScale))
|
||||
pygame.draw.rect(data.display, (255, 255, 255), (0, (y + 1) * data.pixelScale, settings.resolution[0], data.pixelScale))
|
||||
for x in range(int(settings.resolution[0] / data.pixelScale)):
|
||||
unit = pixelsToUnits(x * data.pixelScale, y * data.pixelScale)
|
||||
pygame.draw.rect(data.display, getColor(unit[0], unit[1]), (x * data.pixelScale, y * data.pixelScale, data.pixelScale, data.pixelScale))
|
||||
getInputs()
|
||||
|
||||
# converts a given display pixel into the proper world coordinates.
|
||||
# this is where the zoom and offset are factored in.
|
||||
def pixelsToUnits(x, y):
|
||||
fX = x / settings.resolution[0]
|
||||
fY = y / settings.resolution[1]
|
||||
fX = fX * 2 - 1
|
||||
fY = fY * 2 - 1
|
||||
fX *= settings.scale
|
||||
fY *= settings.scale
|
||||
fX += settings.offset[0]
|
||||
fY += settings.offset[1]
|
||||
return (fX, fY)
|
||||
|
||||
# gets a color for a given coordinate.
|
||||
# this function is just a handler for fractalContains()
|
||||
def getColor(x, y):
|
||||
insideColor = (0, 0, 0)
|
||||
outsideColor = (0, 0, 255)
|
||||
|
||||
val = fractalContains(x, y)
|
||||
if val == -1: return insideColor
|
||||
|
||||
percent = val / settings.fractalIterations
|
||||
percent = sqrt(percent).real
|
||||
return(outsideColor[0] * percent, outsideColor[1] * percent, outsideColor[2] * percent)
|
||||
|
||||
# returns -1 if the point x + yi is contained in the fractal, otherwise
|
||||
# it returns how many iterations it took to be determined outside.
|
||||
# this is also where you can modify the recursive function
|
||||
def fractalContains(x, y):
|
||||
c = complex(x, y)
|
||||
x = c
|
||||
for i in range(settings.fractalIterations):
|
||||
x = x * x + c
|
||||
if x.__abs__() >= 2: return i
|
||||
return -1
|
||||
|
||||
if __name__ == "__main__": main()
|
||||
27
objects.py
Normal file
27
objects.py
Normal file
@ -0,0 +1,27 @@
|
||||
from threading import Thread
|
||||
import pygame
|
||||
|
||||
# this is data for the program, and shouldn't be manually modified
|
||||
class data:
|
||||
display = pygame.Surface
|
||||
monitor = Thread
|
||||
multithreading = bool
|
||||
running = bool
|
||||
pixelScale = int
|
||||
|
||||
# these are user settings. can be set to whatever
|
||||
class settings:
|
||||
# amount of iterations needed for the fractal
|
||||
fractalIterations = 256
|
||||
# beginning upscale level
|
||||
maxPixelScale = 8
|
||||
# ending upscale level
|
||||
minPixelScale = 1
|
||||
# offset in world coordinates
|
||||
offset = (-0.5, 0)
|
||||
# the resolution will work best when set to a power of 2
|
||||
resolution = (512, 512)
|
||||
# zoom level
|
||||
scale = 2
|
||||
# enable/disable multithreading
|
||||
useMultithreading = True
|
||||
22
useful.py
Normal file
22
useful.py
Normal file
@ -0,0 +1,22 @@
|
||||
from cmath import sqrt
|
||||
from random import random
|
||||
|
||||
def magXY(x1, y1, x2, y2):
|
||||
diffX = x2 - x1
|
||||
diffY = y2 - y1
|
||||
return sqrt(diffX * diffX + diffY * diffY).real
|
||||
def magXYZ(x1, y1, z1, x2, y2, z2):
|
||||
diffX = x2 - x1
|
||||
diffY = y2 - y1
|
||||
diffZ = z2 - z1
|
||||
return sqrt(diffX * diffX + diffY * diffY + diffZ * diffZ).real
|
||||
|
||||
def normalizeColor(color):
|
||||
mag = magXYZ(0, 0, 0, color[0], color[1], color[2]) / 255
|
||||
return (color[0] / mag, color[1] / mag, color[2] / mag)
|
||||
|
||||
def randomColor():
|
||||
return (randomInt(255), randomInt(255), randomInt(255))
|
||||
|
||||
def randomInt(max):
|
||||
return int(random() * max)
|
||||
Loading…
x
Reference in New Issue
Block a user