2 Constructors
The examples in this section are easiest to compare when using an auto camera that doesn’t depend on
the
Pict3D instance.
The type and predicate for 3D scenes.
The combine function returns a new Pict3D that contains all of Pict3D
instances in all of its arguments p ....
Usually, the order they’re given in doesn’t affect the result.
When it does, don’t rely on any particular order.
A
Pict3D containing nothing, and a function to detect empty
Pict3Ds.
The first form returns a
Pict3D containing a single rectangle with corners
corner1
and
corner2.
The corners may be any pair that are the opposite endpoints of a main diagonal.
If the second argument is a
direction vector or a scale, the first argument is regarded as a
center point.
If
scale is a direction, the components are interpreted as axis-aligned half-widths.
When
scale is a real number,
(rectangle center scale) is equivalent to
(rectangle center (dir scale scale scale)), and
(cube center scale) is equivalent to
(rectangle center scale).
When inside? is non-#f, the rectangle’s surfaces face inward.
Returns a
Pict3D containing the largest ellipsoid that fits inside
(rectangle corner1 corner2) or
(rectangle center scale).
Example:
When inside? is non-#f, the ellipsoid surface faces inward.
(See rectangle.)
(cylinder | | corner1 | | | | | | | corner2 | | | | | | [ | #:inside? inside? | | | | | | | #:arc arc | | | | | | | #:top-cap? top-cap? | | | | | | | #:bottom-cap? bottom-cap? | | | | | | | #:start-cap? start-cap? | | | | | | | #:end-cap? end-cap? | | | | | | | #:outer-wall? outer-wall?]) | | → | | Pict3D |
|
corner1 : Pos |
corner2 : Pos |
inside? : Any = #f |
arc : Arc = circle-arc |
top-cap? : Any = #t |
bottom-cap? : Any = #t |
start-cap? : Any = #t |
end-cap? : Any = #t |
outer-wall? : Any = #t |
(cylinder | | center | | | | | | | scale | | | | | | | #:<cylinder-keyword> <cylinder-keyword> ...) | | → | | Pict3D |
|
center : Pos |
scale : (U Dir Real) |
<cylinder-keyword> : <cylinder-keyword-type> |
Returns a
Pict3D containing the largest vertical cylinder that fits inside
(rectangle corner1 corner2) or
(rectangle center scale).
When
inside? is non-
#f, the cylinder’s surfaces face inward.
(See
rectangle.)
The remaining boolean arguments determine which parts of the cylinder’s surface are created.
The arc argument determines the start and end angle swept out by the vertical cap
to create the cylinder.
(cone | | corner1 | | | | | | | corner2 | | | | | | [ | #:inside? inside? | | | | | | | #:arc arc | | | | | | | #:bottom-cap? bottom-cap? | | | | | | | #:start-cap? start-cap? | | | | | | | #:end-cap? end-cap? | | | | | | | #:outer-wall? outer-wall?]) | | → | | Pict3D |
|
corner1 : Pos |
corner2 : Pos |
inside? : Any = #f |
arc : Arc = circle-arc |
bottom-cap? : Any = #t |
start-cap? : Any = #t |
end-cap? : Any = #t |
outer-wall? : Any = #t |
(cone | | center | | | | | | | scale | | | | | | | #:<cone-keyword> <cone-keyword> ...) | | → | | Pict3D |
|
center : Pos |
scale : (U Dir Real) |
<cone-keyword> : <cone-keyword-type> |
Returns a
Pict3D containing the largest upward-pointing cone that fits inside
(rectangle corner1 corner2) or
(rectangle center scale).
When
inside? is non-
#f, the cone’s surfaces face inward.
(See
rectangle.)
The remaining boolean arguments determine which parts of the cone’s surface are created.
The arc argument determines the start and end angle swept out by the triangular cap
to create the cone.
(pipe | | corner1 | | | | | | | corner2 | | | | | | [ | #:inside? inside? | | | | | | | #:arc arc | | | | | | | #:bottom-radii bottom-radii | | | | | | | #:top-radii top-radii | | | | | | | #:top-cap? top-cap? | | | | | | | #:bottom-cap? bottom-cap? | | | | | | | #:start-cap? start-cap? | | | | | | | #:end-cap? end-cap? | | | | | | | #:inner-wall? inner-wall? | | | | | | | #:outer-wall? outer-wall?]) | | → | | Pict3D |
|
corner1 : Pos |
corner2 : Pos |
inside? : Any = #f |
arc : Arc = circle-arc |
bottom-radii : Interval = (interval 1/2 1) |
top-radii : Interval = bottom-radii |
top-cap? : Any = #t |
bottom-cap? : Any = #t |
start-cap? : Any = #t |
end-cap? : Any = #t |
inner-wall? : Any = #t |
outer-wall? : Any = #t |
(pipe | | center | | | | | | | scale | | | | | | | #:<pipe-keyword> <pipe-keyword> ...) | | → | | Pict3D |
|
center : Pos |
scale : (U Dir Real) |
<pipe-keyword> : <pipe-keyword-type> |
Returns a
Pict3D containing the largest vertical, hollow cylinder that fits inside
(rectangle corner1 corner2) or
(rectangle center scale).
When
inside? is non-
#f, the pipe’s surfaces face inward.
(See
rectangle.)
The remaining boolean arguments determine which parts of the pipe’s surface are created.
The arc argument determines the start and end angle swept out by a trapezoid to create the
pipe.
The bottom-radii and top-radii intervals give the fractional radius
of the inner and outer wall, on the top and bottom of the pipe.
The fractional radii may exceed 1.
Returns a
Pict3D containing a disk or a ring, placed vertically in the center of the
rectangle defined by
corner1 and
corner2, or by
center and
scale.
When back? is non-#f, the ring surface faces downward.
The arc argument determine the start and end angle swept out by a line to create the ring.
The radii interval argument gives the fractional radii of the inner and outer circle.
Example:
Returns a
Pict3D containing a triangle with the given corners.
By default, the triangle is visible only from viewpoints for which its corners appear to be in
counterclockwise order.
When
back? is
#t, it’s visible only from viewpoints for which its corners appear to
be in clockwise order.
A corner may be either a
position vector or a
vertex.
When a corner is a
Pos instance, its normal is that of the plane the triangle lies in, and
its reflected color, emitted color, and material are the values of
current-color,
current-emitted and
current-material.
A
Vertex instance can override all of these attributes.
All attributes are interpolated across the face of the triangle.
Returns a
Pict3D containing a quadrilateral with the given corners.
The rule for its visibility, and the interpretation of positions and vertices, are the same as
for
triangle.
A quad’s corners are not required to lie in a plane, so its default normal is a best-fit direction
vector computed using Newell’s method.
Returns a
Pict3D containing a point light source at
position, with emitted color
color.
A naive rendering algorithm would take time proportional to n·m, where n is the
number of objects in a scene and m is the number of lights.
Pict3D uses deferred lighting
algorithms that take time proportional to n+m.
Deferred lighting algorithms “draw” each light on every fragment of the rendered scene that
shows a surface the light might illuminate.
An ideal point light illuminates surfaces at any distance, so each ideal point light would have to be
drawn on the entire rendered scene.
Even with these optimizations, lights tend to take more time to render than solid
objects. Try to use only a few thousand well-spaced lights.
Adding ideal point lights quickly becomes prohibitively expensive, so Pict3D restricts each
light’s effect to a light-specific range r.
Instead of forcing a light’s effect to zero at distance r, Pict3D forces smooth attenuation
to zero over a finite range. Forced attenuation starts at distance (/ r 2) and follows a
quadratic curve. The quadratic curve’s first derivative matches the ideal’s curve’s first derivative
at (/ r 2), and is zero at r (so the overall attenuation is
C¹-continuous),
which reduces visual artifacts.
With the default value of
r, forced attenuation starts when ideal attenuation is
4/40 = 0.1, and ends when ideal attenuation would be 1/40 = 0.025.
(See
current-light-range.)
Thus, a single light’s effect with the default
r tends to be hard to distinguish from an
ideal light’s effect.
Much smaller values of
r can result in major discrepancies.
In fact, with #:range 1 in the above example, the light has no apparent effect at all.
Small ranges are useful when a light is used for a local visual effect (such as a magical shine
on a blade) or when many lights in one area slow down rendering too much.
Large ranges are useful when many weak lights illuminate a surface.
Try to choose the smallest large range that gives an effect similar to that of
#:range +inf.0.
The radii argument restricts the light’s area of effect to minimum and maximum
fractions of r.
Here, the light affects surfaces at distances only in the range [30·0.044,30·0.45] = [1.32,1.35].
Transforming a light may change its initially spherical area of effect to an ellipsoid.
This allows lights inside of solid objects to approximate light emission from the objects’ surfaces.
Using many smaller, unscaled lights gives a better approximation, and works well for deformed objects.
The default value producer for
light’s
#:range argument, and its default value.
These are provided to make it easy to change every light’s range at once.
The default value is arrived at by solving the ideal attenuation equation l = i/r²
for r, where i is (emitted-intensity color) and l = 1/40.
That is, it finds the range at which an ideal light’s attenuation is 1/40.
Returns a
Pict3D containing an omnipresent, directional light source.
(arrow start end [#:normalize? normalize?]) → Pict3D
|
start : Pos |
end : Pos |
normalize? : Any = #f |
(arrow | | start | | | | | | | direction | | | | | | [ | #:normalize? normalize?]) | | → | | Pict3D |
|
start : Pos |
direction : Dir |
normalize? : Any = #f |
Returns a
Pict3D containing an arrow drawn from
start to
end, or from
start in the direction
direction.
When
normalize? is non-
#f, the arrow has length
1.
See Position and Direction Vectors for examples.