Link to home
Start Free TrialLog in
Avatar of kretzschmar
kretzschmarFlag for Germany

asked on

qow 16: mystify (all solutions wil be graded)

hi experts,

i am starting a new quest: qow = question of the week :-)
each week i will introduce a new simple? question.

now qow 16

ALL working solutions will get 25 points (a graded).

sorry, top 15 experts, you are not allowed to solve this
q, only other can solve this question :-(

hope, every knows the screensaver mystify,
which comes with windows

now the question is:
i want a app (no screensaver),
which does similar (must not exact) this
on the entire form.
keep in mind, that the canavas get cleared,
if the form is min-/maximized, if you want to draw
on the form-canavas->this is not wanted.
the count of lines should be adjustable at runtime,


ATTENTION:
ALL working solutions will get 25 points (a graded).
(except doubled solutions)

let see

meikl ;-)
Avatar of God_Ares
God_Ares

sorry I don't know mystify, could you provide some sort of screenshot?
Avatar of kretzschmar

ASKER

no window-os, god_ares?
if you have a window-os, go into
-system-preferences
-display
-screensaver-tab
-select mystify from the combobox (is available per default)

well, don't know if it is availabel on xp

meikl ;-)
Sorry no English Windows... all is in dutch.. :(
maybe you find it, if i explain in german
go

-start
-einstellungen
-systemsteuerung
-anzeige
-bildschirmschoner-tab
-in combobox "bildschirmschoner" mystify suchen

or in short
colored lines moving across the screen

meikl ;-)
Mein Deutche Sprache ist nicht so gut, tut mir leight,
are the lines straight or curved?
:-))
>Mein Deutche Sprache ist nicht so gut, tut mir leight
correction:
Meine deutsche Sprache ist nicht so gut, tut mir leid.

as you see, near correct, therefore
your german is better than my dutch,
(knowing no word in dutch) ;-)

as you will,
variations are welcome
Hi Meikl,

Mein deutsch ist auch schrecklich..und ich hab' keine blaße Ahnung wie man 'Mystify' machen kann.
Es versuche mit! ;)
t.
puu, no one knows the mystify-screensaver :-(

hi tongalite,
dein deutsch ist doch gar nicht so übel ;-)
your german isn't so bad ;-)

well, next try
- search with the explorer in the windowsdir/system[32] for the file:
ssmyst.scr
- doubleclick on the file

similar is needed,
variations are welcome

meikl ;-)
found one on web
something like this:

http://www.xs4all.nl/~rutgervd/screen/mystify.zip

meikl ;-)
btw. tongalite,
from where are you?

god_ares,
i guess you are from the netherlands, or?
hi meikl :-)
another good one Q.

Igor.
Meikl,
...bin englander
Und du? Von voher kommst du? (..Welcher Gegenteil Deutschland... das heisst)

I have Mystify on my system.. in fact it's my current screensaver... as of 2 days ago. I also saw a Delphi demo recently that does sort of the same thing. I can't cheat and import the unit because I don't know where I saw it :)

This calls for some experimentation....
Man braucht eben für alles was schwierig ist... viel Geduld!

Später!
t.
Yes, i'm form NL. It's not allowd to draw on the form?
tongalite
ah, ein engländer :-))

well,
i'm from germany,
and there i live in bavaria
and there i live in franconia near nuremberg (nürnberg).
but here are no jobs for delphi-coders,
thats why i earn my money primary as oracle-developer

and at least, this qow is no question which may fast answered, there is one week time

meikl ;-)
>It's not allowd to draw on the form?

yes its allowed, but if you move another window over the form, the lines shouldn't not be (partially) cleared, if you move the other to another side window.

use a tpaintbox for example
instead to draw on the form-canvas

meikl ;-)
instead of lines are also circles,
triangles, bitmaps,
whatever you have in mind allowed
>oracle-developer
oracle forms??? please tell me the made an object orientated language I HATE pl/sql
atleast oracle has a bit done with objects, but not with forms and the objects are not so relyable and good as in other oo-languages.

well, but with the version 9 or 10
forms will be replaced with java.

so i'm coding pl/sql and i don't like it much

meikl ;-)
igor, you like this q?
would you sponsor 25 pts. for the nicest?
I thought you said no entries from the q15 people.
a sponsor is one, who gives somewhat,
i asked igor, if he want to spent 25 pts.
for the nicest app additional

if there comes one

no points for top15
no solution wanted from top15,
except the question is closed or i allow it explicit

a bit kickoff, in 1998 i played a bit with threads

unit PThreaU;
{ zeichnet auf PaintAreal }
{ Bug : Lvscht Linie nicht wenn Anzahl verkleinert wird }
interface

uses
  Classes,windows,sysutils,graphics,ppaper,ptoolu;

Type
  TALine = Record
             Start : TPoint;
             Ende  : TPoint;
             IsPainted : Integer;
             IsDeleted : Boolean;
           End;
type
  ThrPaint = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
  public
    Procedure do_One_Step;
    Constructor Create;
  end;

Var
  StepX1,StepY1,StepX2,StepY2,Anzahl,
  MaxX, MaxY : Longint;


implementation

var
  ALines : Array[0..200] of TALine;
  X1Neg, X2Neg, Y1Neg, Y2Neg,
  Z,P : Longint;


Procedure Init_Array;
Var I : Integer;
Begin
  for i := 0 to 200 do
  Begin
    With ALines[I] do
    Begin
      Start.X := 100;
      Start.y := 100;
      Ende.X := 100;
      Ende.y := 100;
      IsPainted := 0;
      IsDeleted := True;
    End;
  end;
End;

Constructor ThrPaint.Create;
begin
  inherited create(False);
  MaxX := PaintAreal.ClientWidth;
  MaxY := PaintAreal.ClientHeight;
  StepX1 := ToolWindow.STX1.Position;
  StepY1 := ToolWindow.STY1.Position;
  StepX2 := ToolWindow.STX2.Position;
  StepY2 := ToolWindow.STY2.Position;
  Anzahl := ToolWindow.Counter.Position;
  Z := 1;
  X1Neg := 1;
  Y1Neg := 1;
  X2Neg := -1;
  Y2Neg := -1;
  Init_Array;
  PaintAreal.Canvas.Pen.Width := 1;
  FreeOnTerminate := True;
End;

Procedure DeleteALine(OneLine : TALine);
Begin
  With OneLine do
  begin
    PaintAreal.Canvas.Pen.Color := PaintAreal.Color;

    PaintAreal.Canvas.MoveTo(Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    IsPainted := 0;
    IsDeleted := True;
  End;
end;

Procedure DrawALine(OneLine : TALine);
Begin
  With OneLine do
  begin
    If Not(isDeleted) then DeleteALine(OneLine);
    PaintAreal.Canvas.Pen.Color := ClBlack;

    PaintAreal.Canvas.MoveTo(Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(Start.X,MaxY-Start.Y);
    PaintAreal.Canvas.LineTo(Ende.X,MaxY-Ende.Y);

    PaintAreal.Canvas.MoveTo(MaxX-Start.X,Start.Y);
    PaintAreal.Canvas.LineTo(MaxX-Ende.X,Ende.Y);

    IsPainted := 1;
    Isdeleted := False;
  end;
end;



Procedure ThrPaint.do_One_Step;
Begin
  With ALines[Z] do
  begin
    { check if koordinates leave paintareal }
    if (ALines[Z-1].Start.x+(stepx1*X1Neg) > MaxX) or
       (ALines[Z-1].Start.x+(stepx1*X1Neg) < 0) Then X1Neg := -X1Neg;
    if (ALines[Z-1].Start.y+(stepy1*y1Neg) > MaxY) or
       (ALines[Z-1].Start.Y+(stepy1*Y1Neg) < 0) Then Y1Neg := -Y1Neg;
    if (ALines[Z-1].Ende.x+(stepx2*X2Neg) > MaxX) or
       (ALines[Z-1].Ende.x+(stepx2*X2Neg) < 0) Then X2Neg := -X2Neg;
    if (ALines[Z-1].Ende.y+(stepy2*y2Neg) > MaxY) or
       (ALines[Z-1].Ende.y+(stepy2*y2Neg) < 0) Then Y2Neg := -Y2Neg;

   { Set the new coordinates, recognize resize event }

    If Start.X - MaxX > Abs(StepX1) then
      Start.X := MaxX+(stepx1*X1Neg)
    Else
      Start.X := ALines[Z-1].Start.x+(stepx1*X1Neg);
    If Start.Y - MaxY > Abs(StepY1) then
      Start.Y := MaxY+(stepx1*Y1Neg)
    else
      Start.Y := ALines[Z-1].Start.Y+(stepy1*Y1Neg);
    If Ende.X - MaxX > Abs(StepX2) then
      Ende.X := MaxX+(stepX2*X2Neg)
    else
      Ende.X := ALines[Z-1].Ende.x+(stepx2*X2Neg);
    If Ende.Y - MaxY > Abs(StepX1) then
      Ende.Y := MaxY+(stepY2*Y2Neg)
    else
      Ende.Y := ALines[Z-1].Ende.y+(stepy2*y2Neg);
    DrawALine(ALines[Z]);
  End;
  If Z < Anzahl Then P := 200 + Z - Anzahl else P := Z - Anzahl;
  DeleteALine(ALines[P]);
  Inc(Z);
  If Z > 200 Then
  begin
    { round over }
    ALines[0] := ALines[200];
    Z := 1;
  End;
end;

procedure ThrPaint.Execute;
begin
  while True do
  begin
    if Terminated then Terminate;
    Synchronize(Do_One_Step);
  end;
end;

end.

paints one line, does paint mirrored, paint rotated,
just not perfect

meikl ;-)
meikl,

You could have made two questions out of this problem.  First, paint small balls bounding around inside the borders of a form or picturebox canvas.  Secondly, change the balls to endpoints of line segments connected to each other.

Just being helpful. :-)
aikimark,
implement it
kretzschmar , the saver is still available under XP .
ASKER CERTIFIED SOLUTION
Avatar of AvonWyss
AvonWyss
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The compiled executable can be downloaded here:
http://web.bsn.ch/avonwyss/MystifyClone.exe (371kb)
PaintBox with Align=alClient

var
  Form1: TForm1;
  a,olda,aa,oldaa:array[0..3] of tpoint;
  b,oldb,bb,oldbb:array[0..3] of tpoint;
  va,vb:array[0..3] of tpoint;
  first:boolean;

implementation
{$R *.DFM}

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
procedure checkborder(var q,vq:integer;const brd:integer);
begin
  if q>=brd then begin
    q:=2*brd-q;  vq:=-vq;  end;
  if q<0 then begin
    q:=-q;    vq:=-vq;   end;
end;

begin
with paintbox1 do begin
for i:=0 to 3 do begin
  a[i].x:=a[i].x+va[i].x;
  checkborder(a[i].x,va[i].x,clientwidth);
  a[i].y:=a[i].y+va[i].y;
  checkborder(a[i].y,va[i].y,clientheight);
  aa[i].x:=aa[i].x+va[i].x;
  checkborder(aa[i].x,va[i].x,clientwidth);
  aa[i].y:=aa[i].y+va[i].y;
  checkborder(aa[i].y,va[i].y,clientheight);
  b[i].x:=b[i].x+vb[i].x;
  checkborder(b[i].x,vb[i].x,clientwidth);
  b[i].y:=b[i].y+vb[i].y;
  checkborder(b[i].y,vb[i].y,clientheight);
  bb[i].x:=bb[i].x+vb[i].x;
  checkborder(bb[i].x,vb[i].x,clientwidth);
  bb[i].y:=bb[i].y+vb[i].y;
  checkborder(bb[i].y,vb[i].y,clientheight);
end;
canvas.pen.color:=clLime;
if not first then begin canvas.Polygon(olda); canvas.Polygon(oldaa); end;
canvas.Polygon(a);   canvas.Polygon(aa);
olda:=a;    oldaa:=aa;
canvas.pen.color:=clRed;
if not first then begin canvas.Polygon(oldb); canvas.Polygon(oldbb); end;
canvas.Polygon(b);   canvas.Polygon(bb);
oldb:=b;    oldbb:=bb;
first:=false;
end;
end;

procedure TForm1.PaintBox1Click(Sender: TObject);
var i:integer;
begin
with paintbox1 do begin
if not Timer1.Enabled then begin
randomize;
for i:=0 to 3 do begin
  a[i].x:=random(clientwidth-5);
  a[i].y:=random(clientheight-5);
  aa[i].x:=a[i].x+5;
  aa[i].y:=a[i].y+5;
  va[i].x:=(1+random(5))*(2*random(2)-1);
  va[i].y:=(1+random(5))*(2*random(2)-1);
  b[i].x:=random(clientwidth-5);
  b[i].y:=random(clientheight-5);
  bb[i].x:=b[i].x+5;
  bb[i].y:=b[i].y+5;
  vb[i].x:=(1+random(5))*(2*random(2)-1);
  vb[i].y:=(1+random(5))*(2*random(2)-1);
end;
canvas.Brush.color:=clBlack;
canvas.brush.style:=bsSolid;
canvas.fillrect(getclientrect);
canvas.brush.style:=bsClear;
canvas.Pen.Mode:=pmXor;
first:=true;
end;
Timer1.Enabled:=not Timer1.Enabled;
end;
end;
PaintBox with Align=alClient

var
  Form1: TForm1;
  a,olda,aa,oldaa:array[0..3] of tpoint;
  b,oldb,bb,oldbb:array[0..3] of tpoint;
  va,vb:array[0..3] of tpoint;
  first:boolean;

implementation
{$R *.DFM}

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
procedure checkborder(var q,vq:integer;const brd:integer);
begin
  if q>=brd then begin
    q:=2*brd-q;  vq:=-vq;  end;
  if q<0 then begin
    q:=-q;    vq:=-vq;   end;
end;

begin
with paintbox1 do begin
for i:=0 to 3 do begin
  a[i].x:=a[i].x+va[i].x;
  checkborder(a[i].x,va[i].x,clientwidth);
  a[i].y:=a[i].y+va[i].y;
  checkborder(a[i].y,va[i].y,clientheight);
  aa[i].x:=aa[i].x+va[i].x;
  checkborder(aa[i].x,va[i].x,clientwidth);
  aa[i].y:=aa[i].y+va[i].y;
  checkborder(aa[i].y,va[i].y,clientheight);
  b[i].x:=b[i].x+vb[i].x;
  checkborder(b[i].x,vb[i].x,clientwidth);
  b[i].y:=b[i].y+vb[i].y;
  checkborder(b[i].y,vb[i].y,clientheight);
  bb[i].x:=bb[i].x+vb[i].x;
  checkborder(bb[i].x,vb[i].x,clientwidth);
  bb[i].y:=bb[i].y+vb[i].y;
  checkborder(bb[i].y,vb[i].y,clientheight);
end;
canvas.pen.color:=clLime;
if not first then begin canvas.Polygon(olda); canvas.Polygon(oldaa); end;
canvas.Polygon(a);   canvas.Polygon(aa);
olda:=a;    oldaa:=aa;
canvas.pen.color:=clRed;
if not first then begin canvas.Polygon(oldb); canvas.Polygon(oldbb); end;
canvas.Polygon(b);   canvas.Polygon(bb);
oldb:=b;    oldbb:=bb;
first:=false;
end;
end;

procedure TForm1.PaintBox1Click(Sender: TObject);
var i:integer;
begin
with paintbox1 do begin
if not Timer1.Enabled then begin
randomize;
for i:=0 to 3 do begin
  a[i].x:=random(clientwidth-5);
  a[i].y:=random(clientheight-5);
  aa[i].x:=a[i].x+5;
  aa[i].y:=a[i].y+5;
  va[i].x:=(1+random(5))*(2*random(2)-1);
  va[i].y:=(1+random(5))*(2*random(2)-1);
  b[i].x:=random(clientwidth-5);
  b[i].y:=random(clientheight-5);
  bb[i].x:=b[i].x+5;
  bb[i].y:=b[i].y+5;
  vb[i].x:=(1+random(5))*(2*random(2)-1);
  vb[i].y:=(1+random(5))*(2*random(2)-1);
end;
canvas.Brush.color:=clBlack;
canvas.brush.style:=bsSolid;
canvas.fillrect(getclientrect);
canvas.brush.style:=bsClear;
canvas.Pen.Mode:=pmXor;
first:=true;
end;
Timer1.Enabled:=not Timer1.Enabled;
end;
end;
sorry for double post
HI, meikl,
As for this next qow: you want to have a form on which
those lines appears and dissappears as in the "mistery",
and in the same time forbid to paint on the Canvas of the form?
Am I right?
Sincerely,
Nestorua.
>in the same time forbid to paint on the Canvas

no, i just say, you must ensure,
that if a repaint-event of the form
appears the lines are also drawn

meikl ;-)
meikl, have you had the time to look at any of these?
avonwyss,
i have already shown yours
this morning -> cool :-))
hi all,

meikl :-)
I'm here. Yes, I will. Just tell me who deserve it.
Also I will provide my own solution of the task.

-----
Igor
Tried to make it simple :))

object MainForm: TMainForm
  Left = 237
  Top = 103
  Width = 696
  Height = 480
  Caption = 'MainForm'
  Color = clBlack
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnPaint = FormPaint
  OnResize = FormResize
  PixelsPerInch = 96
  TextHeight = 13
  object Timer1: TTimer
    Interval = 60
    OnTimer = Timer1Timer
    Left = 70
    Top = 112
  end
end

unit main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TFigCoord = class
   Place :TPoint;
   xDir  :short;
   yDir  :short;
  public
   constructor CreateBounded(FigCoord: TFigCoord); virtual;
   procedure StepIt;
  end;

  TFigure = class
   Coords :TList;
  public
   constructor Create(Figure: TFigure; CoordsCount: integer); virtual;
   destructor Destroy; override;
   procedure StepIt;
  end;

  TDancer = class
   Color   :TColor;
   Figures :TList;
  public
   constructor Create(FiguresCount: integer; CoordsCount: integer); virtual;
   destructor Destroy; override;
   procedure StepIt; virtual;
  end;

  TMainForm = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure SetDrawBounds;
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
 MainForm: TMainForm;
 Dancers: TList;
 DrawBounds: TPoint;
 Space: integer;

implementation

{$R *.DFM}

{ TFigureCoord }
constructor TFigCoord.CreateBounded(FigCoord: TFigCoord);
begin
 inherited create;
 if FigCoord = nil then
  begin
   Place := Point(Trunc(random(DrawBounds.x)),Trunc(random(DrawBounds.y)));
   xDir  := Trunc(random(2))-1;
   if xDir > -1 then xDir := 1;
   yDir  := Trunc(random(2))-1;
   if yDir > -1 then yDir := 1;
  end
 else
  begin
   Place := FigCoord.Place;
   xDir  := FigCoord.xDir;
   yDir  := FigCoord.yDir;
   StepIt;
  end;
end;

procedure TFigCoord.StepIt;
begin
 Place := Point(Place.x + xDir * Space, Place.y + yDir * Space);
 if not((Place.x > 0) and (Place.x < DrawBounds.x)) then
  begin
   xDir := -xDir;
   if Place.x < 0 then Place.x := abs(Place.x);
   if Place.x > DrawBounds.x then Place.x := 2 * DrawBounds.x - Place.x;
  end;
 if not((Place.y > 0) and (Place.y < DrawBounds.y)) then
  begin
   yDir := -yDir;
   if Place.y < 0 then Place.y := abs(Place.y);
   if Place.y > DrawBounds.y then Place.y := 2 * DrawBounds.y - Place.y;
  end;
end;

{ TFigure }

constructor TFigure.Create(Figure: TFigure;CoordsCount: integer);
var
 i: integer;
begin
 inherited create;
 Coords := TList.Create;
 for i := 0 to CoordsCount-1 do
  if Figure = nil
   then Coords.add(TFigCoord.CreateBounded(nil))
   else Coords.add(TFigCoord.CreateBounded(TFigCoord(Figure.Coords.Items[i])));
end;

destructor TFigure.Destroy;
begin
 Coords.free;
 inherited;
end;

procedure TFigure.StepIt;
var
 i: integer;
begin
 for i := 0 to Coords.Count-1 do
  TFigCoord(Coords.Items[i]).StepIt;
end;

{ TDancer }

constructor TDancer.Create(FiguresCount: integer; CoordsCount: integer);
var
 i      :integer;
 Figure :TFigure;
begin
 if FiguresCount < 1 then raise Exception.create('Dancer must have at least 1 figure!');
 inherited Create;
 color := Trunc(random(65534)+1);
 Figures := TList.Create;
 Figure := TFigure.Create(nil, CoordsCount);
 Figures.Add(Figure);
 for i := 2 to FiguresCount do
  begin
   Figure := TFigure.Create(Figure, CoordsCount);
   Figures.Add(Figure);
  end;
end;

destructor TDancer.Destroy;
begin
 while Figures.Count > 0 do
  begin
   TFigure(Figures.Items[0]).Free;
   Figures.Delete(0);
  end;
 Figures.free;
 inherited;
end;

procedure TDancer.StepIt;
var
 i: integer;
begin
 for i := 0 to Figures.Count-1 do
  TFigure(Figures.Items[i]).StepIt;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
 Space   := 5;
 SetDrawBounds;
 Dancers := TList.Create;
 Dancers.Add(TDancer.Create(2,3));
 Dancers.Add(TDancer.Create(1,4));
 Dancers.Add(TDancer.Create(4,2));
 Dancers.Add(TDancer.Create(10,5));
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
 while Dancers.Count > 0 do
  begin
   TDancer(Dancers.Items[0]).free;
   Dancers.Delete(0);
  end;
 Dancers.free;
end;

procedure TMainForm.FormResize(Sender: TObject);
begin
 SetDrawBounds
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
var
 i: integer;
begin
 for i := 0 to Dancers.Count-1 do
  TDancer(Dancers.Items[i]).StepIt;
 Invalidate;
end;

procedure TMainForm.SetDrawBounds;
begin
 DrawBounds := Point(ClientWidth, ClientHeight);
end;

procedure TMainForm.FormPaint(Sender: TObject);
var
 i,j,k: integer;
begin
 Canvas.brush.Color := clBlack;
// Canvas.FillRect(ClientRect);
 for i := 0 to Dancers.Count-1 do
  begin
   Canvas.Pen.Color := TDancer(Dancers.items[i]).Color;
   for j := 0 to TDancer(Dancers.items[i]).Figures.Count-1 do
    with TFigure(TDancer(Dancers.items[i]).Figures.Items[j]) do
     begin
      Canvas.PenPos := TFigCoord(Coords.items[0]).Place;
      for k := Coords.Count-1 downto 0 do
       Canvas.LineTo(TFigCoord(Coords.items[k]).Place.x, TFigCoord(Coords.items[k]).Place.y);
     end;
  end;
end;

initialization
 Randomize;

end.
Fade effect added, the same link (source and executable)
http://i-g-o-r.virtualave.net/zip/Mystery.zip
wow, igor, very nice,
but, you know you will get no points,
because you're a top15 member,
but it may be a suggestion to all others

meikl ;-)

evaluating now MBo and lottol
thanx meikl,
I know about "no points". I just provide an example to illustrate your question.
It takes all of my yerstaday coffee breaks  :-)
----
Igor.
>It takes all of my yerstaday coffee breaks  
hope you run not out of coffee :-))
I converted my code to screensaver and added settings form:
http://i-g-o-r.virtualave.net/zip/MysterySpline.zip
gradings and next qow comes tomorrow
(no time today)

meikl ;-)
well,
avonwyss code was the nicest
and includes also adjustments,

therefore i raised the points up to 50
(igor you do not need to grade the nicest,
i've already done it now, have enough points,
maybe next time)

mbo,
i got you code not to work with me,
maybe i'm too stupid for copy and paste
(watch out for your 25 points,
because i guess you've tested your code and
it works for you)

lottol,
i got your code work, but its really not so nice as this from avonwyss.
(watch out for your 25 points)

well,
perfect was igor, many thanks to you

thanks to all for participating on this quest

next qow will be a quicky
(first solution will get the points)

meikl ;-)
lottol, MBo

sorry you must wait,
can't nevermore post 25 pts questions :-(
(ex-ex may changed something)


asking at community support now . . .
i'm also unable to post qow 17 :-(
meikl, thanks a lot for the doubled amount of points! Looking forward to the next QOW when you will be able to post it.