User:Thierry Dugnolle/Python/A very little grain of salt

main.py

edit
# 2023, October 19. Version 231019

from Multicolor3Dpainter import aMulticolor3Dpainter
from Vector3D import The3Dvector
from Lattice import TheCubicCell, TheBodyCenteredCubicCell, TheFaceCenteredCubicCell
from Lattice import TheDiamondCell, TheTwoAtomKindsBodyCenteredCubicCell
from time import process_time
import math

print ("Time:", process_time(), "Mathematical painter")

black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)

# The drawer:
TheDrawer = aMulticolor3Dpainter()

# The canvas:
TheCanvasStyle= "color" # "color", "black on white" or "white on black"
TheWidth = 500 # number of pixels
TheHeight = 500 # number of pixels
TheLengthUnit = 200 # number of pixels
TheCanvasColor = white
TheDrawer.takesAnewCanvasMulticolor(TheWidth, TheHeight, TheLengthUnit, TheCanvasStyle, TheCanvasColor)

# The line of vision:
# The angle (in degrees) of the line of vision relative to the z axis:
Theta = 90
# The angle (in degrees) between the projection of the line of vision on the xy plane
# and the x axis:
Phi = 90
# The position of the optical center is determined by the position of the object,
# the direction of the line of vision and the distance between the object and
# the optical center:
# The position of the center of the object:
TheObjectCenter = The3Dvector(0, 0, 0)
# The distance between the object center and the optical center:
TheDistance = 3

# The zoom = 1 means that the image is neither reduced nor enlarged, > 1 that it is enlarged,
# > 0 and < 1 that it is reduced:
TheZoom = 2.2

# Psi is the angle of rotation of the image around the line of vision.
Psi = 0

TheDrawer.choosesApointOfView(TheObjectCenter, TheDistance, Phi, Theta, Psi, TheZoom)

# The paintbrush:
TheDrawer.paintbrush.color = blue # not used here
TheDrawer.paintbrush.lineHalfWidth = 0.015 # (The line half width * the length unit) is the
# number of pixels in the half width of the line.
TheDrawer.brush3D.lineFringeRelativeWidth = 1
TheDrawer.brush3D.lineDepth = 0.1*TheDrawer.paintbrush.lineHalfWidth*(1+TheDrawer.brush3D.lineFringeRelativeWidth)
TheDrawer.brush3D.lineOpacity = 3
TheDrawer.brush3D.atomFringeRelativeWidth = 0
TheDrawer.brush3D.atomOpacity = 10
TheDrawer.brush3D.intensity = 1

# The cell:
TheCellSide = 2
TheBondColor = black
TheAtomRadius1 = 0.3
TheAtomColor1 = blue
TheAtomRadius2 = 0.3
TheAtomColor2 = (0, 128, 0)
TheSaltCell = TheTwoAtomKindsBodyCenteredCubicCell(TheCellSide, TheBondColor,
                TheAtomRadius1, TheAtomColor1, TheAtomRadius2, TheAtomColor2)

# The lattice
width = 5 # Number of cells
depth = width # width # Number of cells
height = width # width # Number of cells
TheSaltCell = TheSaltCell.times(1/width)
TheSaltLattice = TheSaltCell.bondedAtomsLattice(width, depth, height)
TheDrawer.brush3D.lineDepth = 0.1*TheDrawer.paintbrush.lineHalfWidth*(1+TheDrawer.brush3D.lineFringeRelativeWidth)/width

# The animation:
TheNumberOfImages = 400
Theta = 90
for i in range(TheNumberOfImages):
    Phi = i*90/400
    TheDrawer.choosesApointOfView(TheObjectCenter, TheDistance, Phi, Theta, Psi, TheZoom)
    print("Time:", process_time(), "The drawer draws the image", i)
    TheDrawer.takesAnewCanvasMulticolor(TheWidth, TheHeight, TheLengthUnit, TheCanvasStyle, TheCanvasColor)
    TheDrawer.paintsBondedAtomsMulticolor(TheSaltLattice)
    # The folder 'Salt' for the images shall have been created:
    TheDrawer.givesApainting("Salt/im" + str(1000+i) + ".png")
    # str(1000+i) is here because * in imagemagick works with a lexicographic order.

print("Time:", process_time(), "Good bye")

# 400 images are saved in the folder 'Salt'. With imagemagick, they can be united to make a GIF:
# convert -delay 4 -loop 0 im*.png CubicGalaxyAnimation.gif

Other files

edit

This program requires the following additional files: Painter.py, Line2Ddrawer.py, Vector2D.py, Monocolor3Dpainter.py, Vector3D.py, Line3D.py, DepthMatrix.py, Atom.py, Lattice.py and Palette.py. They are all on this page : User:Thierry Dugnolle/Python/Mathematical painter.