unit main;
{AUTOR: Sergio Alex Chávez Rico}
interface
uses
Classes, Controls, Forms,windows, DIBitmap,dialogs,sysutils;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
MOUSE_X,MOUSE_Y:integer;
DIB:TDIB;
procedure Pintar;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
//de Math.pas:
function ArcTan2(Y, X: Extended): Extended;
asm
FLD Y
FLD X
FPATAN
FWAIT
end;
procedure SinCos(Theta: Extended; var Sin, Cos: Extended);
asm
FLD Theta
FSINCOS
FSTP tbyte ptr [edx] // Cos
FSTP tbyte ptr [eax] // Sin
FWAIT
end;
const
ANCHO_BMP_RENDER=512;
ALTO_BMP_RENDER=512;
BITS_POR_PIXEL=16;
procedure TForm1.FormCreate(Sender: TObject);
begin
color:=0;
DIB:=TDIB.Create(self.handle,ANCHO_BMP_RENDER,ALTO_BMP_RENDER,BITS_POR_PIXEL);
DIB.left:=40;
DIB.top:=144;
end;
procedure TForm1.Pintar;
type TPixeles=array[0..ALTO_BMP_RENDER-1,0..ANCHO_BMP_RENDER-1] of word;
var Pixeles:^TPixeles;
procedure PintarEstrellas;
{
De esférico a cilíndrico:
r=p*cos(phi)
theta=theta
h=p*sin(phi)
De cilíndrico a cartesiano:
x=r*cos(theta) //z
y=r*sin(theta)
z=z //x
De cartesiano a cilíndrico:
r = sqrt(x*x+y*y);
theta =arctan2(y/x);
z = z
De esférico a cartesiano:
theta: cilindrico, phi: latitud
x=p*sin(phi)*cos(theta);//z
y=p*sin(phi)*sin(theta);
z=p*cos(phi); //x
}
var i,c,px,py:integer;
phi_0,theta_0,theta_R,theta_R2,phi,theta,r,x,y,z:double;
sin_theta,cos_theta,sin_phi,cos_phi:extended;
begin
Pixeles:=DIB.lpSurface;
bitblt(DIB.DIBhdc,0,0,DIB.width,DIB.height,0,0,0,blackness);
RandSeed:=10101;
theta_R2:=(MOUSE_Y)/1024*pi*2+pi/2;
theta_R:=(MOUSE_X)/1024*pi*2;
for i:=0 to 10000 do
begin
c:=(random(32) shl 5) or (random(32) shl 10);
//definimos en esférico
phi_0:=random*pi*2;
theta_0:=random*pi*2;
{p=1;}
theta:=theta_0+theta_R;//podemos girar de esta forma en esférico
phi:=phi_0;
//pasamos a "cilíndrico eje x":
//primero debemos pasar de esférico a cartesiano
sincos(theta,sin_theta,cos_theta);
sincos(phi,sin_phi,cos_phi);
x:=sin_phi*cos_theta;//z
z:=sin_phi*sin_theta;
y:=cos_phi; //x
//luego de cartesiano a "cilíndrico eje x" (x <-> z):
r := sqrt(sqr(z)+sqr(y));
theta :=arctan2(y,z)+theta_R2;//podemos girar el otro ángulo
z := x;
//luego de "cilíndrico eje x" a cartesiano
sincos(theta,sin_theta,cos_theta);
if (r*cos_theta){z}<0 then continue;//no dibujar los que están "ocultos"
py:=round((z)*254+256);
px:=round((r*sin_theta)*254+256);
pixeles[px and $1ff,py and $1ff]:=c or $3FF;
pixeles[(px+1) and $1ff,py and $1ff]:=c;
pixeles[px and $1ff,(py+1) and $1ff]:=c;
pixeles[(px-1) and $1ff,py and $1ff]:=c;
pixeles[px and $1ff,(py-1) and $1ff]:=c;
end;
end;
begin
PintarEstrellas;
DIB.draw;//Mandar a memoria de video
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DIB.free;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
DIB.draw;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
MOUSE_X:=x;
MOUSE_Y:=y;
pintar;
end;
end.