Home

If you're new to Python
and VPython: Introduction

A VPython tutorial

Introductory Videos

Pictures of 3D objects

What's new

Classic VPython web site
VPython license
Python web site

 
curve
curve

The curve object displays straight lines between points, and if the points are sufficiently close together you get the appearance of a smooth curve.

Details of the curve object

The simplest example of a curve is the following statement, which draws a white straight line of length 2, between the positions < -1,-1,0 > and < 1,--1,0 >:

c = curve(vector(-1,-1,0), vector(1,-1,0))

You can add additional points to this curve like this, completing a square of width 2 whose center is at location < 0,0,0 >:

c.append(vector(1,1,0), vector(-1,1,0), vector(-1,-1,0))

Suppose you have two vectors named v1 and v2. Any of the following schemes will draw a white straight line from postion v1 to position v2:

1) c = curve(v1,v2)

2) c = curve([v1,v2])

3) c = curve(pos=[v1,v2])

4) c = curve(v1)
   c.append(v2)

5) c = curve()
   c.append(v1,v2)

Specifying overall color and radius

By default a curve is white, with a radius of the cross-section of only a few pixels. You can change the default color and radius for all points, using either of the following schemes:

1) c = curve(pos=[v1,v2], color=color.cyan, radius=0.3)

2) c = curve(color=color.cyan, radius=0.3)
   c.append(v1,v2)

Specifying the color and radius of individual points

You can specify the color and radius of individual points that override the color and radius specified for the curve as a whole. The following sequence will create two dictionaries to use as individual points, then will use them to draw a line whose color shades from red to blue and whose radius increases from 0.1 to 0.3:

p1 = dict(pos=v1, color=color.red,  radius=0.1)
p2 = dict(pos=v2, color=color.blue, radius=.3)
curve(p1,p2)

If you prefer, you can create the dictionaries like this:

p1 = {'pos':v1, 'color':color.red,  'radius':0.1}
p2 = {'pos':v2, 'color':color.blue, 'radius':0.3}
curve(p1,p2)

In addition to the attributes pos, color, radius, and emissive, each point has a visible attribute, which makes that particular point visible or invisible. One cannot make a curve transparent (opacity < 1).

Retaining a limited number of points

When creating a curve, or when appending a point to a curve, you can specify how many points should be retained. The following statement specifies that only the most recent 150 points should be retained as you add points to the curve:

c = curve(retain=150)

The following statement specifies that if there are already 30 points in the curve, the oldest one should be deleted and the new point added.

c.append( pos=vector(2,-1,0), retain=30)

The curve attributes

Here is a summary of the attributes for individual points or for the curve as a whole:

pos A vector position or list of positions used in creating a curve. After the curve is created, one must use curve methods such as c.point(N) to read position data.

radius Radius of the cross-section of this segment of the curve; if specified for the curve as a whole, it specifies the radius of any points for which no specific radius was given. The default radius is 0, which makes a thin curve.

color Color of a point; if specified for the curve as a whole, it specifies the color of any points for which no specific color was given.

emissive If True, local and distant lights are ignored, and the brightness is governed by the object's own color. The effect is that the object looks as though it is glowing. The default for emissive is False.

visible If False, point is not displayed; if False for the curve as a whole, no points are displayed.

retain Specify how many points to retain.

A curve also has the standard attributes size, axis, up, shininess, and emissive.

No texture, opacity, or compounding: Currently curves cannot be transparent, it is not possible to apply a texture, and a curve cannot be part of a compound object.

Moving, reorienting, and resizing a curve

Point positions are relative; the use of origin: A point whose pos is vector(2, 1, 0) is of course normally displayed at location vector(2, 1, 0). However, the position of a point is relative to a curve's own origin value, which by default is vector(0, 0, 0). If you change the curve's origin value to vector(10, 6, 5), the point is displayed at the location vector(12, 7, 5); that is, the point is displayed 2 to the right, 6 above, and 0 in front of the curve's position vector(10, 6, 5). Another way of saying this is that the display location is the vector sum vector(10, 6, 5) + vector(2, 1, 0). This means that you can quickly and efficiently move the entire curve just by changing the curve's origin value. The pos value of an individual point does not change; it's just that the point is displayed in a shifted position. As a result, moving an entire curve is very fast.

Similarly, changes to size, axis, up, shininess, and emissive immediately and quickly change the size of the curve, its orientation in space, and the appearance of its surface. When you specify the position of a point, it is relative to an origin at vector(0,0,0) and with the standard axis vector(1,0,0). Changing the size does not change the radius; it just moves the points closer or farther apart.

Rotating a curve

As with other objects, the way to change the orientation of the entire curve is to change the curve's axis. You can also rotate the entire curve about a specified axis. If you don't specify an origin, rotation will occur around the origin of the curve:

c.rotate( angle=ang, axis=a, origin=o )

c.rotate( angle=ang, axis=a )

Curve methods

The basic aspects of the curve object are the same as the Classic VPython curve object. You create a curve and append points to it. However, modifying existing points is not done directly but instead by using a powerful set of functions, and this change makes it possible to display curves much more rapidly. In Classic VPython, the possibility of direct modification of the positions meant that the entire curve had to be reprocessed every time it was rendered, on the chance that some undetected change had occurred.

The following are useful for modifying a curve named "c" (full documentation below):

c.npoints The total number of points currently in the curve.

c.append(...) Add a point or several points to the end.

c.unshift(...) Insert a point or several points at the start.

c.splice(...) Insert a point or several points anywhere.

c.modify(...) Modify the Nth point.

c.clear() Remove all points.

data = c.pop(n) Get the data for point number n and remove it. Can use negative values, where -1 is the last point, -2 the next to the last, etc.

data = c.shift() Get the data for the first point and remove it.

data = c.point(N) Get the data for the Nth point.

data = c.slice(start, end) Get the data for a list of points.

Appending points

Suppose you have created a curve named c. You can add points to the curve one at a time, like this:

c.append(pos=vector(-1,0,0), color=color.red,
            radius=0.05)
c.append(pos=vector(0,1,0), color=color.cyan,
            radius=0.15)
c.append(pos=vector(1,0,0), color=color.red,
            radius=0.05)

This creates the following image:

                                    curve

If you don't need to specify color or radius you can just give a list of positions, either as individual positions or in a list of positions:

c.append( vector(-1,0,0), vector(0,1,0), vector(1,0,0) )
c.append([vector(-1,0,0), vector(0,1,0), vector(1,0,0)])

Suppose you have created a curve named c, and p represents either just a position vector (as just shown above) or a full description of a point:

    p = dict(pos=a vector, color=a vector, radius=a number, visible=True or False)

This can also be written in the form of a Python dictionary:
   p = {'pos':vector, 'color':a vector, 'radius':a number, 'visible':t=True or False}

c.append( p1, p2, p3 ) # add several points

c.append([p1, p2, p3]) # add several points

pts = [p1, p2, p3]
c.append(pts)          # add several points

You can also add several points that all have the same color, radius, etc.:

c.append(pos=[p1, p2, p3], color=color.green)

Manipulating points

Here are details on getting data about points in a curve named "c", or modifying them.

npoints

c.npoints   # the number of points in the curve

append

c.append(...)  # add points at the end (see above)

unshift

c.unshift(p1, p2, p3)  # insert points at start

pts = [p1, p2, p3]
c.unshift(pts)        # insert points at start

The splice method inserts new points starting at location "start" (where 0 is the first point of the curve), deleting "howmany" points before doing the insertion:

c.splice(start,howmany,p1,p2,p3) # insert

pts = [p1, p2, p3]
c.splice(start,howmany,pts) # insert

The modify method lets you change specified attributes of a point::

c.modify(N, # modify point number N
    pos=p, color=c, radius=r, visible=v)
c.modify(N, x=3, y=5) # changing x and y but not z
c.modify(N, vector(x,y,z)) # change only pos

clear

c.clear() # remove all points from curve

pop

data = c.pop()   # get & remove last point
data = c.pop(3)  # get & remove point number 3

shift This is the same as c.pop(0):

data = c.shift() # get & remove first point

point

P = c.point(N) # get a point in the form
      # {'pos':p, 'color':c, 'radius':r, 'visible':v}
      # P['pos'] is p, P['color'] is c, etc.

slice

data = c.slice(2,4) # get a list of
    # points from point no. 2 through point no. 3,
    # each in the form
    # {'pos':p, 'color':c, 'radius':r, 'visible':v}
    # The first point is 0, the last point is -1

Interpolation of colors

The curve machinery interpolates colors from one point to the next. If you want an abrupt change in color, add another point at the same location. In the following example, adding a cyan point at the same location as the orange point makes the first segment be purely cyan.

c = curve(color=color.cyan, radius=0.2)
c.append( vector(-1,0.5,0) )
# add an extra cyan point:
c.append( vector(0,0,0) )
# repeat the same point:
c.append( pos=vector(0,0,0),
         color=color.orange )
# add another orange point:
c.append( pos=vector(1,0.5,0),
         color=color.orange )

In the image shown here, the upper thick curve, made without the second cyan point, has three pos and color points, cyan, orange, orange, left to right, so the blue fades into the orange. The lower curve includes the extra cyan point and has four pos and color points, cyan, cyan, orange, orange, so there is a sharp break between blue and orange.

colors abutting