| Sphere In Cube Movie | Lab Report |
Purpose
The "Sphere in Cube Movie" program generates an animation sequence (50
frames by default) to show a "fly around" of a sphere in a cube.
This "stack" of images can be saved to an animated GIF file.
Materials and Equipment
Software Requirements
Tested with Windows 2000, Delphi 7 (to recompile) [Should work in Win 95 or late, Delphi 3 or later]
SphereInCubeMovie.EXEHardware Requirements
VGA display
Procedure
Discussion
Clicking the Generate button results in a
call to the ButtonGenMovieClick method. In a FOR loop from 0
to SpinEditMaxFrames.Value-1, the following code defines a ViewTransformMatrix,
which automatically transforms each point plotted by DrawCube and DrawSphere
as part of the default transformation of the TPantograph:
// Use FrameIndex in parametric equation to define location of "camera"
// for each frame.
a := ViewTransformMatrix (
// Use spherical coordinates instead of cartesian
coordSpherical,
// azimuth -- cycle around object every 300 Frames
ToRadians(1.2 {degrees} * FrameIndex),
// elevation -- cycle up and down 90 degrees every 90 Frames
ToRadians(90 {degrees} * SIN(ToRadians(4.0*FrameIndex))),
// distance from camera to object -- cycle every 400 Frames
10 + 6*SIN(ToRadians(0.9*FrameIndex)),
// screen parameters: 10x10 from 30 away
10,10,30);
pantograph.SetTransform (a);
DrawCube(PantoGraph, clRed);
DrawSphere(PantoGraph,
{LatitudeColor} clBlue,
{LongitudeColor} clLime,
{LatitudeCircles} 9,
{LongitudeSemicircles} 25,
{PointsInCircle} 40);
|
A TList of Bitmaps, BitmapList, is used to store the sequence of
bitmaps. An EOutOfMemory or an
EOutOfResource error should be trapped if sufficient resources are not present.
The Show button steps through TList and sets the ScrollBar.Position. The side
effect of setting the ScrollBar.Position is to display the appropriate frame in the
animation sequence.
procedure TFormSphereMovie.ScrollBarChange(Sender: TObject);
begin
WITH ImageMovieFrame.Picture.Bitmap DO
BEGIN
// Copy in-memory frame back to screen
Canvas.CopyRect(Rect(0,0, Width,Height),
TNode(BitMapList.Items[ScrollBar.Position]).BitMap.Canvas,
Rect(0,0, Width,Height));
END;
end;
|
The animated "stack" can be saved to a GIF file using code courtesy of Finn Tolderlund in the GIFAnimate.PAS unit. Also required is Anders Melander's GIFImage component. The GIFImage unit can be downloaded from Finn Tolderlund's websites:
http://finn.mobilixnet.dk/delphi
http://home20.inet.tele.dk/tolderlund/delphi
If you do not have TGIFImage installed, change the conditional compilation variable form "GIF" to "NOGIF" (Project | Options | Directories/Conditionals | Conditioanl Defines = NOGIF).
// Thanks to Finn Tolderlund for adding this animated GIF improvement. // This change requires the GIFImage unit from Anders Melander. procedure TFormSphereMovie.MakeGifButtonClick(Sender: TObject);
{$IFDEF GIF}
var
FrameIndex: Integer;
Picture: TPicture;
{$ENDIF}
begin
{$IFDEF GIF}
SavePictureDialog.InitialDir := ExtractFilePath(ParamStr(0));
IF SavePictureDialog.Execute
THEN BEGIN
Screen.Cursor := crHourGlass;
try
GifAnimateBegin;
{Step through each frame in in-memory list}
for FrameIndex := 0 to BitMapList.Count - 1 do
begin
// show user that something is happening
ScrollBar.Position := FrameIndex;
Application.ProcessMessages;
// add frame to animated gif
GifAnimateAddImage(TNode(BitmapList.Items[FrameIndex]).Bitmap,
False, SpinEditMinMillisecondsPerFrame.Value);
end;
// We are using a TPicture but we could have used a TGIFImage instead.
// By not using TGIFImage directly we do not have to add GIFImage
// to the uses clause.
// By using TPicture we only need to add GifAnimate to te uses clause.
Picture := GifAnimateEnd;
try
Picture.SaveToFile(SavePictureDialog.Filename); // save gif
ImageMovieFrame.Picture.Assign(Picture); // display gif
finally
Picture.Free;
end;
finally
Screen.Cursor := crDefault;
end;
END {$ENDIF}
end; |
The GetTickCount API call is used to make sure a minimum amount of time is used
to display each frame in the stack.
The DrawFigures unit can be used to draw a cube, sphere, 3D-surface, or a football field.
Conclusions
A simple animation sequence can be produced by creating
TBitmaps that are displayed in a TImage as quickly as possible, or
saved to a single GIF file as an animated sequence.
Keywords
2D/3D vector graphics, translation, rotation, scaling, view transform, homogeneous
coordinates, clipping, projections, vectors, matrices, TPantograph,
GraphicsPrimitivesLibrary, GraphicsMathLibrary, Delphi
Download
Delphi 7 Source and EXE: SphereInCubeMovie.ZIP
Updated
14 Sep 2004
since 1 Nov 1998