VPython notes .
VPython notes .
Introduction:
Vpython is used to create a web application, animation and simulation.
A Web application (Web app) is an application program that is stored on a remote server and
delivered over the Internet through a browser interface. Web services are Web apps by
definition and many, although not all, websites contain Web apps.
Computer animation is a visual digital display technology that processes the moving images
on screen. In simple words, it can be put or defined as the art or power of giving life,
energy and emotions etc. to any non-living or inanimate object via computers. It can be
presented in form of any video or movie. Computer animation has the ability to make any
dead image alive. The key/main concept behind computer animation is to play the defined
images at a faster rate to fool the viewer so that the viewer should interpret those images as
a continuous motion of images. This animation in programming is shown by changing and
displaying object’s position with time. This animation can be also shown by changing the
size and or colour of the objects or canvas. In the programming these animations can be
managed by incorporating different events in the program. This type of animation is called
as event driven animation.
Applications of animation:
1. Education
2. Demonstration
3. Movie / film, games, entertainment
4. Advertising and marketing
5. Architecture
6. Cartoon
A simulation is a model that mimics the operation of an existing or proposed system, providing
evidence for decision-making by being able to test different scenarios or process changes.
This can be coupled with virtual reality technologies for a more immersive experience.
A simulation is an imitation of the dynamics of a real-world process or system over time.
Although simulation could potentially still be done “by hand,” nowadays it almost always
implicitly requires the use of a computer to create an artificial history of a system to draw
inferences about its characteristics and workings.
The behavior of the system is studied by constructing a simulation model, which usually
takes the form of a set of assumptions about the workings of the system. Once developed, a
simulation model can be used for a variety of tasks, including:
• Investigate the behaviour of the system under a wide array of scenarios. This is also
often referred to as “what-if” analyses;
• During the design stage of a system, meaning while it is being built, simulation can
be used to guide its construction.
Computer simulation has been used in a variety of domains, including manufacturing, health
care, transport system, defence and management science, among many others.
Canvas:
Basically, the Canvas is a rectangular area intended for drawing pictures or other complex
layouts. You can place graphics, text, widgets or frames on a Canvas. A widget is an element
of a graphical user interface that displays information or provides a specific way for a user to
interact with the operating system (OS) or an application. In the context of a web browser, a
frame is a part of a web page or browser window which displays content independent of its
container, with the ability to load content independently. The main advantage of frames is
that it allows the user to view multiple documents within a single Web page. It is possible to
load pages from different servers in a single frameset.
• Bookmarks only bookmark the top level pages (the framesets themselves). A user is
unable to bookmark any of the Web pages viewed within a frame.
• Frames can make the production of a website complicated, although current software
addresses this problem.
• It is easy to create badly constructed websites using frames. The most common
mistake is to include a link that creates duplicate Web pages displayed within a frame.
• Search engines that reference a Web page only give the address of that specific
document. This means that search engines might link directly to a page that was
intended to be displayed within a frameset.
• Users have become so familiar with normal navigation using tables, the back button,
and so on, that navigating through a site that uses frames can be a problem.
• The use of too many frames can put a high workload on the server. A request for, say,
ten files, each 1 Kilobyte in size, requires a greater workload than a request for a
single 10 Kilobyte file.
• Older browsers do not support frames.
• The main advantage of frames is that it allows the user to view multiple documents
within a single Web page.
• It is possible to load pages from different servers in a single frameset.
When using VPython the canvas shows objects in 3D. (0,0,0) is in the center of the canvas.
(0,0,0) x
z
The +x axis runs to the right, the +y axis runs up, and the +z axis points out of the screen,
toward you. x, y, and z are measured in whatever units you choose; the canvas is automatically
scaled appropriately. (You could, for example, create a sphere with a radius of 1E-15 m to
represent a nucleus, or a sphere with a radius of 1E6 m to represent a planet, though it wouldn't
make sense to put both of these objects in the same canvas!)
Syntax for displaying canvas is
mycanvas=canvas(master, option =value,….)
master − This represents the parent window.
options − Here is the list of most commonly used options for this widget. These
options can be used as key-value pairs separated by commas
Sr.No. Option & Description
1 title – for giving title to the animation e.g title= ‘My first Vpython program’. Double
inverting commas also can be used for giving title. You can use the label object to display
text on the canvas. You can also place a title just above the canvas and/or a caption just
below when you create a canvas:
canvas(title='Some title', caption='A caption')
After a canvas has been created you can change the title with scene.title = " " or the
caption with scene.caption = " "
3 resizable - If true (the default), the canvas size can be changed and if false the canvas
size can not be changed. If C is a canvas that is resizable, then C.bind('resize', R) will
execute the function R when the user resizes that canvas. If R has the form def R(ev):,
then ev.event will be 'resize' and ev.canvas will be the canvas C.
4 width – to define width of the canvas in pixel. Default value is 640 pixel and can be
modified e.g. width =100
5 height - to define heigth of the canvas in pixel. Default value is 400 pixel and can be
modified e.g. height =100
6 align -Set to "left" (canvas forced to left side of window), "right" (canvas forced to right side of
window), or "none" (the default alignment). If you have a single canvas, setting align to "left"
causes the canvas caption to be displayed to the right of the canvas. If you want to place a graph
to the right of a canvas, set the canvas align attribute to the string "left" and the graph align
attribute to the string "right". If the window is too narrow, the object that is on the right will be
displayed below the other object. If you want to place a graph to the right of the canvas but keep
the canvas caption underneath the canvas, create the graph first with align set to "right" and
activate the graph by plotting something in it, then create the canvas without specifying its value
of align. Another option is to specify align='left' for all canvases and graphs, in which case they
will about each other.
9 objects -A list of all the visible objects in the canvas; invisible objects and lights are not
listed
10 visible- Setting visible = False means that no objects are displayed, until scene.visible is
set True again.
11 delete()- Deletes all the objects in this canvas and then deletes the canvas itself
12 capture(filename) -Sends to your Download folder a png screen shot of the canvas. If filename
is the string "boxes" or "boxes.png" the file will be named "boxes.png". If you execute
scene.capture("boxes") repeatedly, the additional files will be named "boxes(1).png",
"boxes(2).png", etc. If you do not want to capture "label" objects, execute
scene.capture(filename, False)
14 To obtain the current location of the camera, use scene.camera.pos. camera.follow If you
say scene.camera.follow(ball), the center of the scene will continually be reset to the current
position of the ball object. To stop following the object, execute scene.camera.follow(None).
pixel_to_world - Gives the width of a pixel in "world" coordinates (that is, the coordinates you use to
position objects). This is read-only; you cannot set it. It is determined from the current value of
scene.range. An example of its use is that if you want the radius of a curve object to be 5 pixels, set
the radius to 5*scene.pixel_to_world.
Here are canvas options to wait for canvas updates:
scene.waitfor("redraw") Wait for the start of the next update of the canvas by the web browser
scene.waitfor("draw_complete") Wait for the end of the next update of the canvas by the web browser
Controlling the view
Here is a diagram that shows the relationship among the quantities discussed below that affect how the
scene appears to the viewer:
center Location at which the camera continually looks, even as the user rotates the position of the
camera. If you change center, the camera moves to continue to look in the same direction toward the
new center, unless you also change forward (see next attribute). Default vector(0,0,0).
forward Vector pointing in the same direction as the camera looks (that is, from the current camera
location, given by scene.camera.pos, toward scene.center). When forward is changed, either by
program or by the user using the mouse to rotate the camera position, the camera position changes to
continue looking at center. Default vector(0,0,-1). Its magnitude is not significant.
fov Field of view of the camera in radians. This is defined as the maximum of the horizontal and vertical
fields of view. You can think of it as the angular size of an object of size range, or as the angular size
of the longer axis of the window as seen by the user. Default pi/3.0 radians (60 degrees).
range The extent of the region of interest to the left or right of center. Setting range to 10 means that
scene.center.x+scene.range will be at the right edge of a square window. A sphere of radius 10 will fill
the window. A cubical box whose half-width is 10 will overfill the window, because the front of the box
in 3D appears larger than the xy plane passing through scene.center, unless the field of view is very
small.
up A vector representing world-space up. This vector will always project to a vertical line on the screen
(think of the camera as having a "plumb bob" that keeps the top of the screen oriented toward up). The
camera also rotates around this axis when the user rotates "horizontally". By default the y axis is
the up vector.
There is an interaction between up and forward, the direction that the camera is pointing. By default,
the camera points in the -z direction vector(0,0,-1). In this case, you can make the x or y axes (or
anything between) be the up vector, but you cannot make the z axis be the up vector, because this is
the axis about which the camera rotates when you set the up attribute. If you want the z axis to point
up, first set forward to something other than the -z axis, for example vector(1,0,0).
autoscale = False no automatic scaling (set range explicitly); autoscale = True automatic scaling
(default). It is often useful to let VPython make an initial canvas with autoscaling, then turn autoscaling
off to prevent further automated changes.
userzoom = False user cannot zoom in and out of the scene
userzoom = True user can zoom (default)
userspin = False user cannot rotate the scene
userspin = True user can rotate (default)
userpan = False user cannot pan the scene
userpan = True user can pan (default)
Controlling the view using scene.camera
The mechanisms described above for controlling the view are designed to try to make sure that the
objects are visible no matter how the user rotates or zooms the view, because the camera direction is
always automatically adjusted to point toward scene.center, which by default is at the origin, and
scene.range is automatically adjusted to correspond to the user zoom.
However, if you want to "fly" through the scene, with scene.center necessarily varying but zoom held
constant, it is more convenient to move and point the camera directly. It may possible, when you take
direct control of the camera, there is increased risk of seeing nothing, due to unintentionally pointing
the camera away from the objects, or moving the camera far away from the objects.
An example of controlling the camera directly is the fly-through in the program Stonehenge, in which
changing scene.camera.pos (the location of the camera) and scene.camera.axis (the direction the
camera is pointing) is a convenient way to move through the scene. Using these statements means that
you are controlling the view, so autoscaling is turned off (scene.autoscale is set to False).
scene.camera.pos The current location of the camera, whether due to your own settings, autoscaling,
or as positioned by the user, is scene.camera.pos. For example, mag(scene.center -
scene.camera.pos) is the distance from the current position of the camera to the center of the
scene. The vectors scene.camera.pos and scene.mouse.ray together define all of the 3D points under
the mouse cursor.
You can place the camera where you want it by executing scene.camera.pos = vector(x,y,z). When you
set the camera position in this way, scene.center is reset to the location scene.camera.pos +
scene.camera.axis. The effect is that the camera continues to point in the same direction as before, but
from a new location.
scene.camera.axis The current direction that the camera is pointing, whether due to your own settings,
autoscaling, or as positioned by the user, is scene.camera.axis, which is equal to scene.center -
scene.camera.pos; it points from the camera to scene.center.
When you change scene.camera.axis, scene.camera.pos is unaffected, but scene.center is reset to the
location scene.camera.pos + scene.camera.axis, and scene.forward is reset to norm
(scene.camera.axis).
scene.up Changing scene.up rotates the display around the z axis and would be appropriate for
example if you imagine the camera is attached to an airplane that rotates around its own axis in a turn
or barrel roll.
scene.camera.rotate(angle=..., axis=..., origin=...) As with other VPython objects, you can rotate the
camera by an angle in radians, about a specified axis (which by default is scene.camera.axis), relative
to a specified origin (which by default is scene.camera.pos).
The arrow object has a straight box-shaped shaft with an arrowhead at one end. The following
statement will display an arrow pointing parallel to the x axis:
pointer = arrow(pos=vector(0,2,1), axis=vector(5,0,0), shaftwidth=1)
The arrow object has the following attributes and default values, like those for
cylinders: pos (0,0,0), axis (1,0,0), length (1), color (1,1,1) which is
color.white, red (1), green (1), blue (1), opacity (1), shininess (0.6), emissive (False), texture,
and up (0,1,0). As with box, the up attribute is significant for arrow because the shaft and head
have square cross sections, and setting the up attribute rotates the arrow about its axis.
Additional arrow attributes:
round`- By default, round is False and the arrow has a square cross-section. If round is True, it
has a circular cross-section. The round attribute cannot be changed after creating the arrow.
shaftwidth By default, shaftwidth = 0.1*(length of arrow)
headwidth By default, headwidth = 2*shaftwidth
headlength By default, headlength = 3*shaftwidth
Assigning shaftwidth = 0 makes it be the default (0.1 times the length of the arrow). If you
don't explicitly set headwidth or headlength, its length is based as shown above
on shaftwidth (either the default or whatever value you specify for shaftwidth).
If headlength becomes larger than half the length of the arrow, or the shaft becomes thinner
than 1/50 the length, the entire arrow is scaled accordingly.
This default behavior makes the widths of very short arrows shrink, and the widths of very long
arrows grow (while displaying the correct total length). If you prefer
that shaftwidth and headwidth not change as the arrow gets very short or very long, specify the
desired shaftwidth. In this case the only adjustment that is made is that headlength is adjusted
so that it never gets longer than half the total length, so that the total length of the arrow is
correct. This means that very short, thick arrows look similar to a thumbtack, with a nearly flat
head.
Note that the pos attribute for cylinder, arrow, cone, and pyramid corresponds to one end of
the object, whereas for a box, sphere, or ring it corresponds to the center of the object.
If you include make_trail=True when you create the object, a trail will be left behind the object
as you move it. For related options, see Leaving a Trail.
iii) box:
This is how to create a box object:
mybox = box(pos=vector(x0,y0,z0),length=L, height=H, width=W)
The given position is in the center of the box, at (x0, y0, z0).
This is different from cylinder, whose pos attribute is at one end
of the cylinder. Just as with a cylinder, we can refer to the
individual vector components of the box as mybox.x, mybox.y,
and mybox.z. The length (along the x axis) is L , the height
(along the y axis) is H, and the width is W (along the z axis).
For this box, we have mybox.axis = vector(L, 0, 0) . Note that
the axis of a box is just like the axis of a cylinder.
For a box that isn't aligned with the coordinate axes, additional
issues come into play. The orientation of the length of the box
is given by the axis (see the diagram):
mybox = box(pos=vector(x0,y0,z0), axis=vector(a,b,c), size=vector(L,H,W) )
The axis attribute gives a direction for the length of the box, and here the length, height, and
width of the box are given in terms of "size" (if the length or size is not specified when creating
a box, the length is set to the magnitude of the axis vector).
You can rotate the box around its own axis by changing which way is "up" for the box, by
specifying an up attribute for the box that is different from the up vector of the coordinate
system:
mybox = box(pos=vector(x0,y0,z0),axis=vector(a,b,c), length=L,
height=H, width=W, up=vector(q,r,s))
With this statement, the width of the box will lie in a plane perpendicular to the (q,r,s) vector,
and the height of the box will be perpendicular to the width and to the (a,b,c) vector.
The box object has the following attributes and default values, like those for
cylinders: pos vector(0,0,0), axis vector(1,0,0), up vector(0,1,0), length (1), color (1,1,1)
which is color.white, red (1), green (1), blue (1), opacity (1), shininess (0.6), emissive (False),
and texture. Additional box attributes and details:
height -In the y direction in the simple case, default is 1
width -In the z direction in the simple case, default is 1
size -(length, height, width), default is vector(1,1,1)
v)text:-
With the text object you can display 3D text. The green 3D text shown above was created with
the following statement:
T = text(text='My text is\ngreen', align='center', color=color.green)
Labels were added to the display above to illustrate some of the main attributes of the text
object. Whether you extrude into or out of the screen, the text is created so that it is readable
left to right from the normal viewing position, in the +z direction.
Limitations: It is important to know that this 3D text object is very complex and expensive to
display, nor can you modify the letters displayed once the object has been created. If for
example you want to display rapidly changing text, use the label object (displayed in front of
the canvas) or the wtext object (displayed above the canvas as part of the title or below the
canvas as part of the caption).
Currently this 3D text object does not handle HTML options, such as bold, italic, subscript, or
superscript. The label and wtext objects do however support these options.
3D text is made out of quads and triangles which are then made into a compound object for
speed of display. You can make additional copies of a text object by cloning it. You can move
the text by specifying a new pos, and you can change its axis, up, color, opacity, shininess,
and emissive, as with other objects, but note that color and size are "multiplicative".
The 3D text object does not have a size attribute. Instead, the size of the display is specified
by height, length and depth as discussed below.
Here is a list of text attributes, in addition to the usual attributes of canvas, color, shininess, and
opacity (but not texture or bumpmap, currently):
pos -The location of the baseline of the text, to the left, to the right, or at the center of the text,
as per align.
align -Specify 'left' (default), 'right', or 'center'.
text -The text to be displayed, such as "My text is\ngreen" in the example above ('\n' is a new-
line character). Unicode strings are supported. After creating the object, the text is read-only -
- it cannot be changed. The reason for this is that it takes a significant portion of a second to
create a 3D text object. If you need to change the text, make the current object invisible
(visible=False) and create a new object. The text need not be a string; it can be anything that
you could print.
height -Height of an uppercase letter (see above); default is 1. Specifying the height when
creating the text object sets the scale for the entire text display. After creating the 3D text, you
can change the height of the object. For example, if you say T.height = 0.5*T.height, the letters
become shorter but the length stays the same. Changing the height also changes descent and
vertical_spacing.
length - length of the displayed text. You cannot specify a length when creating the 3D text,
but you can change this later. For example, if you say T.length = 0.5*T.length, the letters
become narrower but the height stays the same.
depth - Depth of the text; the default is 0.2 times the height when creating the 3D text. A
positive number means extrude toward you, out of the screen; negative means extrude away
from you, into the screen. After creating the 3D text, you can change this. For example, if you
say T.depth = 2*T.depth, the letters become twice as thick. If the depth is zero, the thickness
is made to be 0.01 times the height, and the text looks like a thin sheet.
font- Name of the desired font, either "sans" (sans serif, the default) or "serif". This is read-
only.
billboard- In computer graphics "billboard" behavior means that the object always faces you,
no matter how you reorient the camera. Specifying billboard = True when creating the text
turns this on, and then is read-only. Because lighting changes as you rotate the camera, you
may wish to specify emissive = True, so that the text is always bright.
color- The color of the text.
start_face_color and end_face_color -By default,the starting and ending faces are given the
same color as the rest of the text, as specified by color, but you can specify that other colors be
used for the starting or ending face of the extruded text.
show_start_face and show_end_face -By default, these attributes are True and the start and end
faces of the extruded text are displayed. If you set one of these to False, that face is left open.
descender- Height of the descender on lower-case letters such as y (whether or not there is such
a letter in the text). This is typically about 0.3 times the height. This is read-only but is affected
by changes in height.
upper_left, upper_right, lower_right, lower_left- The bounding box of the displayed text; all of
these are read-only. For example, if you create title = text(text="My Text"), you can place a
sphere at the upper left corner with the statement sphere(pos=title.upper_left). See the screen
display above.
start, end -The left-most and right-most locations on the baseline. These are read-only. If align
is 'left', pos is the same as start. If align is 'right', pos is the same as end.
vertical_spacing -Vertical distance from one baseline to the next in a multiline text. This is
read-only.
Axis- The axis points along the baseline; changing the axis changes the orientation of text. The
default is vector(1,0,0), with text going toward the right. Changing the axis only affects the
direction of the line of text, not the length or size.
up -Controls the up attribute of the text; changing up makes the text tip away from the vertical.
vi) ring:
The ring object is by default circular, with a specified radius and thickness and with its center
given by the pos attribute:
ring(pos=vector(1,1,1), axis=vector(0,1,0), radius=0.5, thickness=0.1)
The ring object has the following attributes and default values, similar to those for
cylinders: pos vector(0,0,0), axis vector(1,0,0), length (0.2), color vector(1,1,1) which is
color.white, red (1), green (1), blue (1), opacity (1), shininess (0.6), emissive (False), texture,
and up (0,1,0). As with cylinders, up has a subtle effect on the 3D appearance of a ring unless
a non-smooth texture is specified or the ring is oval. The axis attribute only affects the
orientation of the ring; the magnitude of the axis attribute is irrelevant. Additional ring
attributes:
radius -Radius of the central part of the ring, default = 1, so
outer radius = radius+thickness
inner radius = radius-thickness
Setting radius overrides the size attribute. Note that size.x = 2*thickness and in a circular ring
size.y = 2*(radius + thickness).
thickness -The radius of the cross section of the ring (1/10th of radius if not specified), not the
full diameter as you might expect. Note that size.x = 2*thickness and in a circular ring size.y
= 2*(radius + thickness).
size -Instead of specifying radius and thickness, you can make the ring be oval by specifying
its size as size=vector(length,height,width), with different height and width. Setting thickness
overrides the size attribute.
Note that the pos attribute for cylinder, arrow, cone, and pyramid corresponds to one end of
the object, whereas for a ring, sphere, and box it corresponds to the center of the object.
If you include make_trail=True when you create the object, a trail will be left behind the object
as you move it. For related options, see Leaving a Trail.
Note -similar explanation for ellipsoid, frame, point, extrusion, helix, label,pyramid, vertex,
triangle,quad.
In VPython we can define our own attribute by using following syntax
object_name.attribute=quantity
Loops: same as python
Each line of code gives the computer a task (for example: make a sphere, print are, etc.), and
it goes through the lines obne by one and follows those directions. If one wanted the
computer to do the same task over and over again until you tell it to stop, where one can use
a loop.
1. Initialization of a variable
2. A test to see if some condition has been met
3. Calculations or other operations (like print) using the variable
4. A small addition (increment) to the variable
e.g.
num=0
while num<11:
print(“Number=”, num)
num=num+1
print(“Now loop is completed, let us move to the next part of the code”)
• The line num = 0 initializes the variable t. Initializing a variable just means to create it
and give it a value so that it's ready for use on a later line of code.
• The line while num < 11: tells the computer do keep doing whatever you write in the
loop until t is no longer less than 11. Notice that whatever is inside the loop is
indented.
• The line print("Number=",num) is inside the loop, and therefore gets repeated every
time the computer runs through the loop.
• The line num = num +1 is also inside the loop and also gets repeated. This line is
important because it is changing t. We told the computer to only repeat the loop as
long as num < 11 was true. Eventually, by adding 1 every time, num will be greater
than 10, and the loop will end.
Callbacks
Here is a simple example of how to use callbacks to process click events:
s = sphere(color=color.cyan)
def change():
if s.color.equals(color.cyan):
s.color = color.red
else:
s.color = color.cyan
scene.bind('click', change)
We define a "function" named "change". Then we "bind" this function to click events occurring
in the canvas named "scene". Whenever VPython detects that a click event has occurred,
VPython calls the bound function, which in this case toggles the sphere's color between cyan
and red.
This operation is called a "callback" because with scene.bind you register that you want to be
called back any time there is a click event. Here are the built-in events that you can specify in
a bind operation:
Mouse: click, mousedown, mousemove, mouseup
Keyboard: keydown, keyup
Other: redraw, draw_complete
The event 'mousedown' or 'mouseup' occurs when you press or release the left button on the
mouse, and the 'mousemove' event occurs whenever the mouse moves, whether or not a button
is depressed. A 'redraw' event occurs just before the 3D scene is redrawn on the screen, and a
'draw_complete' event occurs just after the redrawing (these event have rather technical uses
such as timing how often redrawings occur, or how much time they take).
You can bind more than one event to a function. The following will cause the callback function
to be executed whether you press or release the mouse button:
scene.bind('mouseup mousedown', change)
Another use of callbacks is to drive a function periodically. See the example program Bounce-
Callbacks-VPython. Also see the related documentation for the
functions get_library() and read_local_file().
Details of the event
You can get detailed information about the event by writing the callback function like this (note
the variable 'evt' in parentheses):
def info(evt):
print(evt.event, evt.pos)
Here we specify an argument in the definition of the callback function ('evt' in this case). When
the function is called due to a specified event happening, VPython sends the function
information about the event. The name of the argument need not be 'evt'; use whatever name
you like. In addition to evt.event, evt.pos, and evt.pick, there is further event information in the
form of evt.press and evt.release which are 'left' for press or release events.
The quantity evt.event will be 'keydown' if a key was pressed. The quantity evt.which is the
numerical key code or mouse button indicator (mouse button is always 1 for now). For
example, evt.which is 65 for the 'a' key. Note that scene.mouse.shift is true if the shift key is
down at the time of the keyboard event; similarly for scene.mouse.ctrl and scene.mouse.alt.
In classic VPython you can optionally have VPython send the callback function an additional
argument, but this is not currently possible in Web VPython.
Right or middle button mouse events
There is currently no way in Web VPython to handle right button or middle button events.
Unbinding
Suppose you executed scene.bind('mousedown mousemove', Drag), but now you no longer
want to send mousemove events to that function. Do this:
scene.unbind('mousemove', Drag)
Custom events: triggers (works in Web VPython but currently not with installed Python)
It is possible to create your own event type, and trigger a function to do something. Consider
the following example, where the custom event type is 'color_the_ball':
def clickFunc():
s = sphere(pos=scene.mouse.pos, radius=0.1)
scene.trigger('color_the_ball', s)
def ballFunc(ev):
# ev.type is "color_the_ball"; ev.event is the new sphere
ev.event.color=color.cyan
scene.bind('click', clickFunc)
scene.bind('color_the_ball', ballFunc)
box(pos=vector(1,0,0))
We bind click events to the function clickFunc, and we bind our own special event type
'color_the_ball' to the function ballFunc. The function clickFunc is executed when the user
clicks the mouse. This function creates a small sphere at the location of the mouse click, then
triggers an event 'color_the_ball', with the effect of passing to the function ballFunc
information that includes the new sphere object. Finally ballFunc applies a color to the sphere.
This program displays a box, then repeatedly waits for a mouse left click and displays a cyan
sphere at the mouse location. A mouse click is defined as pressing and releasing the left mouse
button with no motion of the mouse, so the sphere appears when you release the mouse button.
scene.range = 4
box() # display a box for context
def showSphere(evt):
loc = evt.pos
sphere(pos=loc, radius=0.2, color=color.cyan)
scene.bind('click', showSphere)
Copy this program into an edit window and run the program. Click outside the box and a cyan
sphere appears where you click. If you click inside the box, nothing seems to happen. This is
because the mouse click is in the xy plane, and the sphere is buried inside the box. If you rotate
the scene and then click, you'll see that the spheres go into the new plane parallel to the screen
and passing through scene.center.
If you want all of the spheres to go into the xy plane, perpendicular to the z axis, change the
latter part of the program like this:
loc = scene.mouse.project(normal=vector(0,0,1))
# loc is None if no intersection with plane
if loc:
sphere(pos=loc,radius=0.2,color=color.cyan)
Drag Example
Here is the sequence of mouse events involved in dragging something:
1) Determine that the mouse button has been depressed (a mousedown event).
2) Continually watch for the mouse to move, and use scene.mouse.pos to update positions.
These are mousemove events.
3) Conclude the drag when the mouse button has been released (a mouseup event).
The way you detect these mouse events is by writing functions that are bound to the mouse
events using scene.bind, and Web VPython will execute these functions when these mouse
events occur.
Here is a complete routine for repeatedly creating and dragging a sphere, so that you can
arrange many spheres on the screen. While being dragged the sphere is red, but its color
changes to cyan when the mouse button is released.
scene.range = 5
box()
drag = False
s = None # declare s to be used below
def down():
global drag, s
s = sphere(pos=scene.mouse.pos,
color=color.red,
size=0.2*vec(1,1,1))
drag = True
def move():
global drag, s
if drag: # mouse button is down
s.pos = scene.mouse.pos
def up():
global drag, s
s.color = color.cyan
drag = False
scene.bind("mousedown", down)
scene.bind("mousemove", move)
scene.bind("mouseup", up)
It is also possible to use "anonymous" (unnamed) functions, an extended feature of the
RapydScript-NG Python-to-JavaScript compiler, as shown here (this will NOT work with
installed Python):
scene.range = 5
box()
drag = False
s = None # declare s to be used below
Other mouse events: You can also watch for mouseenter (the mouse is moved from the
outside of the canvas to the inside), mouseleave (the mouse leaves the canvas), and click.
Multiple event types: You can bind a function to more than one type of event. Here is a
function bound to both mousedown and mouseup events, either of which will cause a sphere
to be created:
scene.bind("mousedown mouseup", def ():
sphere(pos=scene.mouse.pos)
Unbinding: After binding a function to a mouse event, you can unbind the function, in which
case Web VPython will no longer send events to your function. In the program shown above,
if you place scene.unbind("mousedown") in the mouseup event, you will be able to drag just
one sphere.
Just one: If you use scene.one instead of scene.bind, the binding occurs for just one event and
then is automatically unbound. In the program shown above, if you specify scene.one for the
mousedown event, you will be able to drag just one sphere.
Custom events: You can set up your own custom events using scene.trigger. In the following
sample program, first you see a box, then the while loop halts waiting for the custom "ball"
event to occur. When you click, the function t is executed, and in this function a sphere is
created and a new type of event, "ball", is triggered by scene.trigger, with the optional argument
b, representing the new sphere. With this triggering of a "ball" event, function f receives the
triggered arguments in ev and sets the sphere's color to blue. The triggering of a "ball" event
also breaks through the scene.waitfor in the while loop that was waiting for a "ball" event. The
process in the loop then repeats.
def t():
b = sphere(pos=scene.mouse.pos, radius=0.2)
scene.trigger("ball", b)
scene.bind("click", t)
def f(ev):
# ev.type is "ball"; ev.event is newball
ev.event.color = color.blue
scene.bind("ball", f)
cube = box(pos=vec(-2,0,0))
while True:
s = scene.waitfor("ball")
print(s.type, s.event.pos) # "ball" and the new sphere's pos
cube.rotate(angle=0.1, axis=vec(0,0,1))
Keyboard Interactions
As with mouse events, you can wait for various kinds of keyboard or mouse events:
scene.waitfor('keydown') # wait for keyboard key press
scene.waitfor('keyup') # wait for keyboard up key release
scene.waitfor('click keydown') # click or keyboard
scene.waitfor('click') # wait for a click
scene.waitfor('mousedown') # wait for mouse button press
scene.waitfor('mouseup') # wait for mouse button release
scene.waitfor('mousemove') # wait for mouse to be moved
scene.waitfor('mousedown mousemove') # either event
The event 'keydown' or 'keyup' occurs when you press or release a key on the keyboard (if you
hold down a key, you may get multiple 'keydown' events due to repeats). Keyboard events are
not actually associated with particular canvases, but mouse events are, and the capability of
waiting for both keyboard and mouse events makes it necessary to name a canvas, such as
"scene".
You can obtain a package of information about the event that caused the end of the wait:
box()
ev = scene.waitfor('click keydown')
if ev.event == 'click':
print('You clicked at', ev.pos)
else:
print('You pressed key '+ev.key)
def keyInput(evt):
s = evt.key
if len(s) == 1: # includes enter ('\n')
prose.text += s # append new character
elif s == 'delete' and len(prose.text) > 0:
prose.text = prose.text[:-1] # erase letter
scene.bind('keydown', keyInput)
We define a "function" named "keyInput". Then we "bind" this function to 'keydown' events
occurring in the canvas named "scene". Whenever VPython detects that a 'keydown' event has
occurred, VPython calls the bound function, which in this case adds the input to the text of the
label object.
Note that evt.ctrl, evt.alt, and evt.shift are True if the corresponding key is down at the time of
the event (evt.shift is also True if Caps Lock is in effect). Also, for a keyboard event evt.type is
'keydown' or 'keyup' and evt.which is the numerical code for the key.
This operation is called a "callback" because with scene.bind you register with VPython that
you want to be called back any time there is a 'keydown' event. Here are the built-in events that
you can specify in a bind operation:
Keyboard: keydown, keyup
Mouse: click, mousedown, mousemove, mouseup
Other: redraw, draw_complete
The event 'keydown' or 'keyup' occurs when you press or release a key on the keyboard. The
events 'click', 'mousedown', 'mousemove', and 'mouseup' are discussed in the mouse section.
A 'redraw' event occurs just before the 3D scene is redrawn on the screen, and a
'draw_complete' event occurs just after the redrawing (these event have rather technical uses
such as timing how often redrawings occur, or how much time they take).
You can bind more than one event to a function. The following will cause the callback function
to be executed whether you click with the mouse or press a key on the keyboard:
scene.bind('click keydown', myFunction)
With the following statement, click event will no longer be sent to myFunction:
scene.unbind('click', myFunction)
Animation:
Computer animation is a visual digital display technology that processes the moving images
on screen. In simple words, it can be put or defined as the art or power of giving life,
energy and emotions etc. to any non-living or inanimate object via computers. It can be
presented in form of any video or movie. Computer animation has the ability to make any
dead image alive. The key/main concept behind computer animation is to play the defined
images at a faster rate to fool the viewer so that the viewer should interpret those images as
a continuous motion of images. This animation in programming is shown by changing and
displaying object’s position with time. This animation can be also shown by changing the
size and or colour of the objects or canvas. In the programming these animations can be
managed by incorporating different events in the program. This type of animation is called
as event driven animation.
One important method use in the animation loop is rate(frequency). It is used to halts
computations until 1.0/frequency seconds after the previous call to rate().
For example, rate(50) will halt computations long enough to make sure that at least 1.0/50.0 =
0.02 second has elapsed. If this much time has already elapsed, no halt is performed. If you
place rate(50) inside a computational loop, the loop will execute at a maximum of 50 times per
second, even if the computer can run faster than this. This makes animations look about the
same on computers of different speeds, as long as the computers are capable of carrying out 50
computations per second.
It is obligatory to place a rate statement in an animation loop. Without it, no screen updates or
processing of mouse or keyboard events are possible.
Another option is to use the function sleep: sleep(0.02) means "don't do anything for 0.02
seconds" and is equivalent to rate(50). The sleep function periodically renders the scene and
processes mouse events, making it possible to continue using zoom and rotate, whereas the
standard Python function time.sleep(t) does not do this.
Applications of animation:
1. Education
2. Demonstration
3. Movie / film, games, entertainment
4. Advertising and marketing
5. Architecture
6. Cartoon
scaling objects:
In the animation, when the object is moving along the x or y axis there is no or in xy plane
there is no question of changing the size of the object. But if there is motion in Z-direction i.e.
the object is moving either away from you where the object size must be decrease
proportionally or the object is moving towards the positive z-axis direction, it means that the
object is coming towards you. In the later case the size of the object must be increase in
proportion. The proportionality constant between the original size and the final size is called
as a scaling factor. Another example is when one wants to show the direction and the magnitude
of velocity of projectile motion. The direction is shown by an arrow pointing to different
directions at every point (tangent to the curve at that point). Also the length of the arrow gives
the magnitude. In other words, the length of the arrow reflects magnitude of the velocity. Thus,
the length of the arrow must change in proportional to the velocity of the object. This
proportionality constant i.e. scaling factor I given by
scale factor=desired object size / present size of the object