I Started Learning Visual Python (vPython)

What is Virtual Python?

Visual Python, also known as vPython, is a library that allows you to create 3D visualizations and animations in Python. It’s particularly useful for teaching and learning physics and computer programming because it provides an easy-to-use interface for creating interactive 3D graphics. Visual Python is based on the popular Python programming language and is designed to be user-friendly, making it accessible to both beginners and experienced programmers.

Where to Begin

Learn Python:

If you have never used Python before you can follow our latest crash course here: Python Crash Course Rev.3 (Updated 2023)

Visual Python Installation:

To get started with vPython, you’ll need to install it first. As of my last knowledge update in September 2021, vPython was typically installed using the vpython package, which you can install using pip. However, please note that software and package installations can change, so it’s a good idea to check the official vPython website or documentation for the most up-to-date installation instructions.

Here’s how you can install vPython using pip:

pip install vpython

Creating a Basic VPython Program:

Once you have vPython installed, you can create a basic vPython program to display a 3D object. Here’s a simple example:

from vpython import sphere, scene

# Create a 3D scene
scene.background = color.white
scene.title = "VPython Example"

# Create a 3D object (in this case, a sphere)
my_sphere = sphere(pos=vector(0, 0, 0), radius=1, color=color.blue)

# Run the VPython interactive window
while True:
    rate(30)  # Adjust the frame rate as needed

In this example:

  • We import the necessary VPython modules, sphere and scene.
  • We create a 3D scene and set its background color and title.
  • We create a 3D sphere object and specify its position, radius, and color.
  • Finally, we enter an infinite loop with rate(30) to keep the VPython window open and update the scene at 30 frames per second.

You can interact with the 3D object using your mouse and keyboard. You can rotate the view, zoom in and out, and even animate the objects as needed.

Additional Resources:

To learn more about vPython and explore its capabilities, you can refer to the official VPython documentation and tutorials. Since the software and documentation may have been updated since my last knowledge update, it’s a good idea to visit the official VPython website or relevant community resources for the latest information and examples:

These resources should provide you with more in-depth information and examples to help you get started with vPython and create interactive 3D visualizations in Python.

Some Basic Scripts

Here is some of the work I have done so far:

Basic Clock

Visual Python Clock Animation

Using Pythons time library, this basic script displays the time.

The Code:
from vpython import *
import numpy as np
import time

clockR=2
clockT=clockR/10
majorTickL=clockR/7
majorTickT=2*np.pi*clockR/300
majorTickW=clockT*1.2
minorTickL=clockR/15
minorTickT=2*np.pi*clockR/600
minorTickW=clockT*1.2
minHandL=clockR-majorTickL
minHandT=minHandL/25
minHandOffset=clockT/2+minHandT
hrHandL=.75*minHandL
hrHandT=minHandT*1.25
hrHandOffset=clockT+hrHandT
secHandL=clockR-majorTickL
secHandT=minHandL/25
secHandOffset=clockT/2+minHandT
hubRadius=clockT/1.5

hrAngle=np.pi/2
minAngle=np.pi/2
secAngle=np.pi/2

secInc=-.01
minInc=secInc/60
hrInc=minInc/12

for theta in  np.linspace(0,2*np.pi,13):
    majorTick=box(axis=vector(clockR*np.cos(theta),clockR*np.sin(theta),0),color=color.black,length=majorTickL,width=majorTickW,height=majorTickT,pos=vector((clockR-majorTickL/2)*np.cos(theta),(clockR-majorTickL/2)*np.sin(theta),0))
for theta in  np.linspace(0,2*np.pi,61):
    minorTick=box(axis=vector(clockR*np.cos(theta),clockR*np.sin(theta),0),color=color.black,length=minorTickL,width=minorTickW,height=minorTickT,pos=vector((clockR-minorTickL/2)*np.cos(theta),(clockR-minorTickL/2)*np.sin(theta),0))

myTime=time.localtime(time.time())
print("Hour: "+str(myTime[3]))
print("Minute: "+str(myTime[4]))
print("Second: "+str(myTime[5]))
print(str(myTime[3])+":"+str(myTime[4])+":"+str(myTime[5]))

clockFace=cylinder(radius=clockR,axis=vector(0,0,1),color=vector(1,1,1),length=clockT,pos=vector(0,0,-clockT/2))
minHand=arrow(axis=vector(0,1,0),length=minHandL,color=color.black,shaftwidth=minHandT,pos=vector(0,0,minHandOffset))
hrHand=arrow(axis=vector(0,-1,0),length=hrHandL,color=color.black,shaftwidth=hrHandT,pos=vector(0,0,hrHandOffset))
secHand=arrow(axis=vector(0,1,0),length=secHandL,color=color.red,shaftwidth=secHandT,pos=vector(0,0,secHandOffset))
hub=cylinder(axis=vector(0,0,1),length=clockT*2,radius=hubRadius,color=color.black)
textH=clockR/4
myLabel=text(text="GMT Time Zone",align="center",color=color.red,height=textH,pos=vector(0,1.1*clockR,-clockT/2),depth=clockT)
Angle=np.pi/2
AngleInc=-2*np.pi/12
Angle=Angle+AngleInc
numH=clockR/8
for i in range(1,13,1):
    clockNum=text(align="center",text=str(i),pos=vector(clockR*.75*np.cos(Angle),clockR*.75*np.sin(Angle)-numH/2,0), height=numH,depth=clockT,color=color.black)
    Angle=Angle+AngleInc

while True:
    rate(5000)
    hr=time.localtime(time.time())[3]
    min=time.localtime(time.time())[4]
    sec=time.localtime(time.time())[5]
    minAngle=-((min+sec/60)/60)*2*np.pi+np.pi/2
    hrAngle=-((hr+min/60)/12)*2*np.pi+np.pi/2
    secAngle=-(sec/60)*2*np.pi+np.pi/2
    minHand.axis=vector(minHandL*np.cos(minAngle),minHandL*np.sin(minAngle),0)
    hrHand.axis=vector(hrHandL*np.cos(hrAngle),hrHandL*np.sin(hrAngle),0)
    secHand.axis=vector(secHandL*np.cos(secAngle),secHandL*np.sin(secAngle),0)

Bouncing Ball Animation

Visual Python Bouncing Ball Animation
The Code:
from vpython import *
from time import *


####PLAY AROUND WITH THESE SETTINGS ONLY####
wallThickness=1       
roomWidth=20
roomDepth=30
roomHeight=50
bSpeed=100 #Ball Speed
mRadius=2 #Marble Radius
############################################

floor=box(pos=vector(0,-roomHeight/2,0),size=vector(roomWidth, wallThickness, roomDepth),color=color.green)
ceiling=box(pos=vector(0,roomHeight/2,0),size=vector(roomWidth, wallThickness, roomDepth),color=color.green)
leftWall=box(pos=vector(-roomWidth/2,0,0),size=vector(wallThickness, roomHeight, roomDepth),color=color.green)
rightWall=box(pos=vector(roomWidth/2,0,0),size=vector(wallThickness, roomHeight, roomDepth),color=color.green)
back=box(pos=vector(0,0,-roomDepth/2),size=vector(roomWidth, roomHeight, wallThickness),color=color.green)
marble=sphere(radius=mRadius,color=color.red)

deltaX=.1
deltaY=.1
deltaZ=.1

xPos=0
yPos=0 #x,y,z Starting Positions
zPos=0

while True:
    rate(bSpeed)
    xPos=xPos+deltaX
    yPos=yPos+deltaY
    zPos=zPos+deltaZ
    Xrme=xPos+mRadius #Xrme right marble edge
    Xlme=xPos-mRadius #Xlme left marble edge
    Ytme=yPos+mRadius #Ytme Top marble edge
    Ybme=yPos-mRadius #Ybme Bottom marble edge
    Zbme=zPos-mRadius #Zbme Back marble edge
    Zfme=zPos+mRadius #Zfme Front marble edge
    Rwe=roomWidth/2-wallThickness/2 #Rwe Right wall edge
    Lwe=-roomWidth/2+wallThickness/2 #Lwe Left wall edge
    Cwe=roomHeight/2-wallThickness/2 #Cwe Ceiling wall edge
    Flwe=-roomHeight/2+wallThickness/2 #Flwe Floor wall edge
    Bwe=-roomDepth/2+wallThickness/2 #Bwe Back wall edge
    Fwe=roomDepth/2-wallThickness/2 #Fwe Front wall edge

    if (Xrme>=Rwe or Xlme<=Lwe):
        deltaX=deltaX*(-1)
    if (Ytme>=Cwe or Ybme<=Flwe):
        deltaY=deltaY*(-1)
    if (Zfme>=Fwe or Zbme<=Bwe):
        deltaZ=deltaZ*(-1)

    marble.pos=vector(xPos,yPos,zPos)

Adding User Interactive Functionality

Visual Python with interactive functions
The Code:
from vpython import *
from time import *

wallThickness=.1       
roomWidth=12
roomDepth=20
roomHeight=15
mRadius=.5 #Marble Radius
bSpeed=1
floor=box(pos=vector(0,-roomHeight/2,0),size=vector(roomWidth, wallThickness, roomDepth),color=color.green)
ceiling=box(pos=vector(0,roomHeight/2,0),size=vector(roomWidth, wallThickness, roomDepth),color=color.green)
leftWall=box(pos=vector(-roomWidth/2,0,0),size=vector(wallThickness, roomHeight, roomDepth),color=color.green)
rightWall=box(pos=vector(roomWidth/2,0,0),size=vector(wallThickness, roomHeight, roomDepth),color=color.green)
back=box(pos=vector(0,0,-roomDepth/2),size=vector(roomWidth, roomHeight, wallThickness),color=color.green)
marble=sphere(radius=mRadius,color=vector(1,1,1))
deltaX=.1
deltaY=.1
deltaZ=.1
xPos=0
yPos=0 #x,y,z Starting Positions
zPos=0

#First Widget
run=0

def runRadio(x):
    print(x.checked)
    global run
    if x.checked==True:
        run=1
    if x.checked==False:
        run=0
radio(bind=runRadio, text="Run")

scene.append_to_caption("\n\n")
#Second Widget
def bigBall(x):
    global mRadius
    if x.checked==True:
        mRadius=mRadius*2
        marble.radius=mRadius
    if x.checked==False:
        mRadius=mRadius/2
        marble.radius=mRadius
checkbox(bind=bigBall,text="Big Ball")

scene.append_to_caption("\n\n")

#Third Widget
def ballRed(x):
    marble.color=color.red
def ballGreen(x):
    marble.color=color.green
def ballBlue(x):
    marble.color=color.blue    
button(bind=ballRed,text="Red",color=vector(0,0,0),background=vector(1,0,0))
button(bind=ballGreen,text="Green",color=vector(0,0,0),background=vector(0,1,0))
button(bind=ballBlue,text="Blue",color=vector(0,0,0),background=vector(0,0,1))

#Fourth Widget
def ballOpac(x):
    op=x.value
    marble.opacity=op
slider(bind=ballOpac,vertical=False,min=0,max=1,value=1,text="Opacity")

#Fifth Widget
def speed(x):
    global bSpeed
    if x.selected=="x1":
        bSpeed=1
    if x.selected=="x2":
        bSpeed=2
    if x.selected=="x3":
        bSpeed=3
    if x.selected=="x4":
        bSpeed=4
    if x.selected=="x5":
        bSpeed=5
menu(bind=speed, choices=["x1","x2","x3","x4","x5"])
wtext(text="Speed")
while True:
    rate(25)
    xPos=xPos+deltaX*run*bSpeed
    yPos=yPos+deltaY*run*bSpeed
    zPos=zPos+deltaZ*run*bSpeed
    Xrme=xPos+mRadius #Xrme right marble edge
    Xlme=xPos-mRadius #Xlme left marble edge
    Ytme=yPos+mRadius #Ytme Top marble edge
    Ybme=yPos-mRadius #Ybme Bottom marble edge
    Zbme=zPos-mRadius #Zbme Back marble edge
    Zfme=zPos+mRadius #Zfme Front marble edge
    Rwe=roomWidth/2-wallThickness/2 #Rwe Right wall edge
    Lwe=-roomWidth/2+wallThickness/2 #Lwe Left wall edge
    Cwe=roomHeight/2-wallThickness/2 #Cwe Ceiling wall edge
    Flwe=-roomHeight/2+wallThickness/2 #Flwe Floor wall edge
    Bwe=-roomDepth/2+wallThickness/2 #Bwe Back wall edge
    Fwe=roomDepth/2-wallThickness/2 #Fwe Front wall edge

    if (Xrme>=Rwe or Xlme<=Lwe):
        deltaX=deltaX*(-1)
    if (Ytme>=Cwe or Ybme<=Flwe):
        deltaY=deltaY*(-1)
    if (Zfme>=Fwe or Zbme<=Bwe):
        deltaZ=deltaZ*(-1)

    marble.pos=vector(xPos,yPos,zPos)

Multi-Time Zone Clock with a Little Extra

Conclusion

Visual Python opens up a world of possibilities for creating captivating 3D visualizations and animations with ease. Whether you’re a beginner looking to explore the fundamentals of programming or an experienced developer seeking to communicate complex ideas visually, vPython empowers you to turn your imagination into reality. Its user-friendly interface, rich documentation, and supportive community make it a valuable tool for both education and professional projects. So, dive into the realm of vPython and embark on a journey where code and creativity converge in a visually stunning way.

Luke Barber

Hello, fellow tech enthusiasts! I'm Luke, a passionate learner and explorer in the vast realms of technology. Welcome to my digital space where I share the insights and adventures gained from my journey into the fascinating worlds of Arduino, Python, Linux, Ethical Hacking, and beyond. Armed with qualifications including CompTIA A+, Sec+, Cisco CCNA, Unix/Linux and Bash Shell Scripting, JavaScript Application Programming, Python Programming and Ethical Hacking, I thrive in the ever-evolving landscape of coding, computers, and networks. As a tech enthusiast, I'm on a mission to simplify the complexities of technology through my blogs, offering a glimpse into the marvels of Arduino, Python, Linux, and Ethical Hacking techniques. Whether you're a fellow coder or a curious mind, I invite you to join me on this journey of continuous learning and discovery.

Leave a Reply

Your email address will not be published. Required fields are marked *

Verified by MonsterInsights