Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Hypotrochoid generator
- import Image, ImageDraw
- import math
- #Size of canvas to draw on
- #Higher resolution means thinner lines, but may need higher resolution below
- canvasX = 5760
- canvasY = 3240
- #Size of final image
- imageX = 1920
- imageY = 1080
- #Background color
- bgcolor = "black"
- #Coordinates of center of image
- centerX = canvasX / 2
- centerY = canvasY / 2
- resolution = 6000 #Number of points calculated and drawn per half rotation
- revolutions = 350 #Number of times the disc goes around the rim
- rimRadius = 1620.0 #Radius of rim/outer circle
- rimRadians = 0 #Keeps track of the rotations around the rim
- disc1Radius = 630.0 #Radius of disc with pen holes in it
- disc1HoleRadius = 600.0 #Dist of hole from disc center, <= discRadius
- disc1inside = -1 #-1 if disc1 is inside rim, 1 if outside
- disc1rotSpeed = 1.0 #1.0 for normal, lower->slower, higher->faster
- disc1Radians = 0.0 #Keeps track of disc 1 rotation
- useSecondDisc = True #enaTruebles a second disc
- disc2Radius = 300.0 #Radius of disc with pen holes in it
- disc2HoleRadius = 120.0 #Dist of hole from disc center, < discRadius/2
- disc2inside = 1 #-1 if disc2 is inside disc1, 1 if outside
- disc2rotSpeed = 0.1 #1.0 for normal, lower for slower, higher for faster
- disc2Radians = 0.0 #Keeps track of disc 2 rotation
- #Used for finding the center of the discs
- ratio1 = disc1Radius/rimRadius
- ratio2 = disc2Radius/disc1Radius
- #Color options, see colorMethod function below
- rColor = 2
- gColor = 2
- bColor = 1
- def colorMethod(methodNum, x, y):
- if methodNum == 0: #No color added
- return 0
- elif methodNum == 1: #Full color added
- return 255
- elif methodNum == 2: #Based on distance from center
- distance = math.sqrt(((x - centerX)*(x - centerX))+\
- ((y - centerY)*(y - centerY)))
- return int((distance/rimRadius)*255)%255
- elif methodNum == 3: #Based on distance from center (reversed)
- distance = math.sqrt(((x - centerX)*(x - centerX))+\
- ((y - centerY)*(y - centerY)))
- return int(255-((distance/rimRadius)*255))%255
- elif methodNum == 4: #Based on polar coordinates of draw point
- if x - centerX == 0:
- return 0
- else:
- temp = (math.atan((y-centerY)/(x-centerX))) / (math.pi*2)
- temp = int(16 * temp * 255) % 510
- if temp <= 255:
- return temp
- else:
- return 510 - temp
- elif methodNum == 5: #Based on rimRadians
- temp = rimRadians / (math.pi*2)
- temp = int(temp) % 510
- if temp <= 255:
- return temp
- else:
- return 510 - temp
- elif methodNum == 6: #Based on disc1Radians
- temp = disc1Radians / (math.pi*2)
- temp = int(temp) % 510
- if temp <= 255:
- return temp
- else:
- return 510 - temp
- #Open the image and prepare to draw to it
- print "Creating image..."
- myImage = Image.new("RGB", (canvasX,canvasY), bgcolor)
- draw = ImageDraw.Draw(myImage)
- #Note: sin and cos may be switched to shift rotation of entire image slightly
- while rimRadians < (math.pi * 2 * revolutions):
- #Coordinates for center of disc. Finds point of contact between
- #disc and rim, then subtracts radius of disc
- disc1CenterX = (1+(disc1inside*ratio1)) * rimRadius*math.sin(rimRadians)
- disc1CenterY = (1+(disc1inside*ratio1)) * rimRadius*math.cos(rimRadians)
- #Finds radians disc1 has rotated
- #Or if second disc used, find radians disc2 has rotated around disc1
- disc1Radians = disc1rotSpeed * (rimRadians * rimRadius / disc1Radius)
- if not useSecondDisc: #Using one disc, like a normal spirograph
- #Calculate where the pen hole is
- drawPointX = disc1CenterX + disc1HoleRadius*math.sin(-disc1Radians)
- drawPointY = disc1CenterY + disc1HoleRadius*math.cos(-disc1Radians)
- else: #Using a second disc rotating around the first disc
- #Find the center of the center disc
- disc2CenterX = disc1CenterX + ((1+(disc2inside*ratio2)) * \
- disc2Radius*math.sin(disc1Radians))
- disc2CenterY = disc1CenterY + ((1+(disc2inside*ratio2)) * \
- disc2Radius*math.cos(disc1Radians))
- #Find radians disc2 has rotated
- disc2Radians = disc2rotSpeed * (rimRadians * rimRadius / disc2Radius)
- #Calculate where the pen hole is
- drawPointX = centerX + disc2CenterX + disc2HoleRadius*math.sin(-disc2Radians)
- drawPointY = centerY + disc2CenterY + disc2HoleRadius*math.cos(-disc2Radians)
- #Draw the point
- colorTuple = (colorMethod(rColor, drawPointX, drawPointY),\
- colorMethod(gColor, drawPointX, drawPointY),\
- colorMethod(bColor, drawPointX, drawPointY))
- draw.point((drawPointX, drawPointY), fill=colorTuple)
- #Rotate around the rim
- rimRadians += (math.pi/resolution)
- #Stop drawing and save the image
- del draw
- myImage = myImage.resize((imageX,imageY), Image.ANTIALIAS)
- myImage.save("hypotrochoid.png", )
- print "Completed!"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement