Inleiding Dit artikel beschrijft hoe je in Delphi 3 dimensionale bollen kunt tekenen.Er is een testprogramaatje toegevoegd en het hele Delphi-7 project kan gedownload worden. (kijk onderaan deze pagina) Opmerkelijk genoeg is er geen ingewikkelde wiskunde nodig: de stelling van Pythagoras en lineaire functies volstaan. Er zijn een paar schuifjes toegevoegd om de lichtinval en intensiteit van de kleuren in te stellen. Het artikel beschrijft die ook. Een kleur kiezen gebeurt met één van de zeven speedbuttons, die in een array staan dat op runtime gecreëerd wordt. fig.1 hieronder toont een verkleind beeld van het 3D bollen programma. De kleuren De kleuren op de bol veranderen lineair van het punt met de grootste intensiteit naar de randen.Dit suggereert prima een driedimensionaal effect. Het is onnatuurlijk om een kleur te veranderen van bijvoorbeeld rood naar blauw. Alleen de intensiteit moet veranderen. Daarom hoeven we alleen de intensiteit te berekenen, die loopt van 0 (donker) naar 255 (licht). Daarna bepaalt een 3 bits code welke kleuren er meedoen. colorcode bit -0- selecteert rood, bit -1- groen en bit -2- blauw. Op design time is de colorcode opgeborgen in de tag property van de bijbehorende speed button. Zie figuur 2. Het tekenen van de bol Dat gebeurt in bitmap Smap. (S - Sphere)Alle pixels worden doorlopen van links naar rechts en boven naar onder. Per pixel wordt getest of de positie binnen of buiten de bol ligt. Zie figuur 3 Bekijk eens punt P(x,y). rx en ry zijn de horizontale- en vertikale afstanden tot middelpunt M.
ry := y - centerY
en ook de coördinaten op de bol waar de lichtintensiteit maximaal is. Om het rekenwerk te versimpelen wordt even aangenomen dat middelpunt M op (0,0) ligt. Relatief t.o.v. M zijn focusX en focusY de coördinaten met maximale intensiteit (focuspunt):
focusY := Yposition – centerY Als (px,py) de afstand is tot het focuspunt dan:
py := ry – focusY
Variabelen CCint en BCint bevatten de intensiteit (0..255) van focuspunt en rand. Een goed 3D effect wordt verkregen door de intensiteit lineair te laten verlopen (opmerkelijk). Per pixellengte verandert de intensiteit met de waarde (max intensity - min.intensity)/(focus - border) dus:
wegens het pf32 bit format van de bitmap. De scanline[..] property wordt slechts twee keer gebruikt om de pointer naar pixel[0,0] te krijgen en de afstand tussen twee lijnen te berekenen. Dit maakt zeer snel tekenen mogelijk. De properties pixels[..] en scanline[..] zijn erg traag. De schuifjes Die worden getekend in paintboxen.Xbox controleert de horizontale focus positie, Ybox de vertikale positie. CCbox controleert de centrum-intensiteit, BCbox de rand-intensiteit. De volgende condities kunnen op een schuifje van toepassing zijn: type TSlidestatus = (stIdle,stOnSpot,stLocked); var slidestatus : Tslidestatus; slidestatus = stIdle geeft aan dat er geen aktie plaatsvindt. De muiswijzer staat niet boven een pijltje. slidestatus = stOnSpot geeft aan dat de muiswijzer boven een pijltje staat. slidestatus = stLocked geeft aan dat muiswijzer "onSpot" staat met muisknop ingedrukt. Als de muisknop wordt ingedrukt bij status slidestatus = stOnSpot dan wordt de slidestatus stLocked. Daarna kan de pijlpositie veranderen met mousemove events. slidestatus wordt weer stIdle na een mouseUp event. Deze methode is van toepassing op alle pijltjes. De mouseDown en mouseMove events methods zijn gescheiden per paintbox. In de source code zien we ook de variabele Offset. Offset is niet strikt nodig omdat de pijltjes maar klein zijn. Fig. 5 hieronder demonstreert de noodzaak als er een groter object verplaatst wordt. een rechthoek kan horizontaal worden verschoven. X is de muispointer bij een mouseDown event. Door te berekenen:
X is de positie van het object. Tekenen van de pijltjes. Bekijk figuur 6. voor het tekenen van een horizontaal pijltje.Het startpunt van de tekening is tevens de positie van het pijltje. Penbewegingen voor de X- en Y-richtingen staan in een apart array[1..7]. Zie procedure paintRightArrow voor details. Merk op, dat een oud pijltje eerst gewist moet worden voordat een nieuw in de paintbox kan worden getekend. Er kan natuurlijk een klasse worden gemaakt om bollen te tekenen, maar hier is daarvan afgezien. Het project Klik [ hier ] voor het gehele Delphi-7 project. |
||||||||