PDA

Ver la Versión Completa : Dibujar Elipse y Parábola pixel a pixel


Deiv
19-11-2006, 15:38:59
Conociendo las fórmulas matemáticas de la construcción de una Elipse, me preguntaba como dibujarlo pixel por pixel, es decir empezar en cierto lugar, recorrer según su fórmula, y terminar en el mismo punto donde empezó.

Imagino que, para mostrarlo debo realizarlo con un TTimer, pero mi pregunta va dirigida más a conocer aquella ruta de construcción (dibujado) de esa Elipse, ya que requiero hacer mover un objeto por esa trayectoria, algo así como el movimiento de un Planeta alrededor del Sol por así decirlo, pero necesito saber en que coordenada de la Elipse se encuentra el planeta.

JF Sebastian
19-11-2006, 16:06:06
puedes hacerlo facilmente mediante coordenadas polares tomando como variable independiente el angulo ro algo asi como:

txy(a,0);
pd;
for i := 0 to 360 step 2 do
begin
ro := sqrt(a^2*b^2/(b^2*cos(i)^2+a^2*sin(i)^2));
txy(ro*cos(i),ro*sin(i));
end;


Esta tomado de un interprete que me hice para el trazado de perfiles metalicos mediante graficos de tortuga, pero te puede dar una idea de como hacerlo.

Saludos

Deiv
19-11-2006, 17:06:23
No tengo Delphi a mano, lo probaré en casa. Solo viendo así el código: ¿y como detectar una posición (las coordenadas) en ese trazado en una TImage? Como dije mi objetivo es hacer mover un objeto por la ruta (alrededor) de elipse, y en algún momento necesitaré saber donde se encuentra el objeto en esa TIMage.

seoane
19-11-2006, 20:10:58
Según entendí lo que tu quieres son las coordenadas de la elipse y con ellas poder hacer lo que quieras, dibujar la elipse o mover un objeto siguiendo esa trayectoria. Sea como sea, aquí te dejo una función, que pasándole como parámetros x1,y1,x2,y2 (que tienen el mismo significado que en la función de dibujo) y el ángulo entre 0 y 2pi nos devuelve las coordenadas del punto correspondiente de la elipse.


function EllipsePoint(X1,Y1,X2,Y2: Integer; Angulo: Double): TPoint;
var
Cx,Cy,A,B: Double;
begin
A:= abs(X2-X1)/2;
B:= abs(Y2-Y1)/2;
Cx:= (X1+X2)/2;
Cy:= (Y1+Y2)/2;
Result.X:= Trunc(Cx + A * cos(Angulo));
Result.Y:= Trunc(Cy - B * sin(Angulo));
end;


Por ejemplo si queremos dibujar la elipse:

var
i: integer;
P: TPoint;
begin
P:= EllipsePoint(10,10,300,100,0);
Canvas.MoveTo(P.X,P.Y);
for i:= 1 to 360 do
begin
P:= EllipsePoint(10,10,300,100,(Pi*i)/180);
Canvas.LineTo(P.X,P.Y);
end;
end;


O si queremos mover un botón a lo largo de la trayectoria:

var
i: integer;
P: TPoint;
begin
for i:= 0 to 360 do
begin
P:= EllipsePoint(10,10,300,100,(Pi*i)/180);
Button1.Left:= P.X;
Button1.Top:= P.Y;
Application.ProcessMessages;
Sleep(10);
end;
end;

Deiv
19-11-2006, 22:02:05
Vuelvo de casa después de implementar la orientación de JF Sebastian,
Pues lo he dibujado así con el código de abajo, imagino que deben ser las matemáticas, pero este me dibuja solo un cuadrante de la Elipse en el TIMage (cuadrante IV)

procedure TForm1.Timer1Timer(Sender: TObject);
var
x,y,radio:extended;
P1,P2,a,b,angulo:integer;
begin
radio:= 40;
a:=5;
b:=2;
for angulo:= 1 to 360 do
begin
x := radio*a*cos(angulo);
y := radio*b*sin(angulo);
P1:= StrToInt(FloatToStr(int(x)));
P2:= StrToInt(FloatToStr(int(y)));
Image1.Canvas.Pixels[P1,P2]:= clBlue;
end;
//Image1.Repaint;
end;
Como dije solo me dibuja el IV cuadrante, debe ser que me estoy ubicando mal en el TImage; otra cosa, el Timer no me dibuja muy bien los pixels, pareciera que lo hiciese como un Random, ¿alguna sugerencia?

Es un problemita no tener conexión Internet en casa, siempre me valgo de un CyberCafe, y estoy leyendo en este momento el código de Seoane, lo probaré regresando, y luego responderé, bueno?.

JF Sebastian
20-11-2006, 09:13:05
tienes que pasar los grados a radianes entre otras cosas...

Deiv
20-11-2006, 13:35:38
He revisado el código de Seoane, y...... sinceramente es lo que necesitaba, agradecerte una vez mas "Salvador Allende" ("Salvador Seoane")
Gracias.

Tuvan
03-11-2016, 03:49:44
Vengo siguiendo un tema que llevo en la universidad por varios casos como este en el foro y siempre me encuentro con las respuestas de Seoane te doy gracias amigo sabiendo que llevas tiempo sin actividad, tus respuestas me han dado mucha ayuda.
Es lo que buscaba, con esto termino de entender lo que estudiaba.
Gracias de nuevo

Tuvan
03-11-2016, 09:16:17
Según entendí lo que tu quieres son las coordenadas de la elipse y con ellas poder hacer lo que quieras, dibujar la elipse o mover un objeto siguiendo esa trayectoria. Sea como sea, aquí te dejo una función, que pasándole como parámetros x1,y1,x2,y2 (que tienen el mismo significado que en la función de dibujo) y el ángulo entre 0 y 2pi nos devuelve las coordenadas del punto correspondiente de la elipse.


function EllipsePoint(X1,Y1,X2,Y2: Integer; Angulo: Double): TPoint;
var
Cx,Cy,A,B: Double;
begin
A:= abs(X2-X1)/2;
B:= abs(Y2-Y1)/2;
Cx:= (X1+X2)/2;
Cy:= (Y1+Y2)/2;
Result.X:= Trunc(Cx + A * cos(Angulo));
Result.Y:= Trunc(Cy - B * sin(Angulo));
end;


Por ejemplo si queremos dibujar la elipse:

var
i: integer;
P: TPoint;
begin
P:= EllipsePoint(10,10,300,100,0);
Canvas.MoveTo(P.X,P.Y);
for i:= 1 to 360 do
begin
P:= EllipsePoint(10,10,300,100,(Pi*i)/180);
Canvas.LineTo(P.X,P.Y);
end;
end;


O si queremos mover un botón a lo largo de la trayectoria:

var
i: integer;
P: TPoint;
begin
for i:= 0 to 360 do
begin
P:= EllipsePoint(10,10,300,100,(Pi*i)/180);
Button1.Left:= P.X;
Button1.Top:= P.Y;
Application.ProcessMessages;
Sleep(10);
end;
end;



Me ha salido de maravilla el codigo, pero ahora esta es la situacion, quiero hacer lo mismo que el botón pero lo he cambiado por un Timage

Sólo me faltaria marcar la ruta por la que pasa con una linea e irla marcando poco a poco con sleep.

La finalidad de mi animación es dibujar un patrón aleatorio de posibles elipses pero soy un poco malo en trigonométria, espero puedan ayudarme

Casimiro Notevi
28-11-2016, 10:19:41
...
Bienvenido a clubdelphi, como siempre aconsejamos a los nuevos, no olvides leer nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php), gracias por tu colaboración :)

Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)