The last code works, but i realize that when we put a sprite on screen (with DisplaySprite() or similar function), we are drawing it onto both two buffers, but not with 2D drawing commands. So this is a corrected:
Code: Select all
;----------------------------------------------------------------------------
;Son 2 algoritmos bien distintos que hacen girar circularmente un item
;alrededor de un punto (centro).
;La hazana es que en ninguno de los dos se usa la trigonometria y por
;tanto son muy rapidos.
;----------------------------------------------------------------------------
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitPalette(10) = 0
MessageRequester("Error", "Can't open DirectX", 0)
End
EndIf
DefType .f
#bitplanes=8 ; =====> 256 colores
#RX=800:#RY=600
If OpenScreen(#RX,#RY,#bitplanes,"")=0:End:EndIf
LoadPalette(1,"Sprites\h2.bmp")
DisplayPalette(1)
LoadSprite(0,"Sprites\h2.bmp",0)
SW.w=SpriteWidth(0):SH.w=SpriteHeight(0)
MouseLocate(#RX/2,#RY/2)
ExamineMouse():x=MouseX():y=MouseY()
Gosub text
GrabSprite(1,x,y,SW,SH,0)
FlipBuffers()
Gosub text
X_r=61:Y_r=0 ;Inicializacion del vector director del radio.
d=1/30 ;Velocidad de giro. El signo da el sentido del giro (en la primera rutina).
k=Sqr(1+Pow(d,2))
c=Sqr(2+Pow(d,2)+1/Pow(d,2))
Repeat
ExamineMouse()
Gosub r
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_LeftControl)
ReleaseMouse(1):FreeSprite(1):FreeSprite(0):FreePalette(1):CloseScreen()
End
;**********************************************************************************
r:
If MouseButton(1)
xr=X_r:yr=Y_r ;Actualizo vector director del radio (distancia desde el
;centro al objeto)=(x,y)->(x+xr,y+yr).
xa=-yr*d:ya=xr*d ;(xa,ya) es un vector normal al (xr,yr)
;pero con el modulo multiplicado por la
;constante preestablecida d.
xold=x:yold=y
x=MouseX():y=MouseY() ;Actuales coordenadas del centro
DisplayTransparentSprite(0,x,y);draw our mouse pointer sprite just here
Gosub draw;<--Draw on this buffer
FlipBuffers();<--swap buffers
DisplaySprite(1,xold,yold);<--restore the old background
GrabSprite(1,x,y,SW,SH,0);<--and save the new one
Gosub draw;<--Draw on this buffer
X_r=(xa+xr)/k:Y_r=(ya+yr)/k ;Nuevo vector director del radio.
;NOTA: Probar con X_r=(xa-xr)/k:Y_r=(ya-yr)/k
;Se suman los vectores directores (xa,ya)
;y (xr,yr) dando lugar a un vector director
;hipotenusa del triangulo formado por
;aquellos dos. Este nuevo vector debe
;ser recortado para que su modulo sea
;el de el radio, o sea el de el cateto
;(xr,yr). Dicho recorte viene dado por
;la cte. k, establecida como sqr(1+d^2)
;(NOTA: teorema de pitagoras y proporcio-
;nalidad de triangulos).
;Ahora (X_r,Y_r) es el nuevo vector director,
;o sea, el que se buscaba.
ExamineMouse()
;NOTA: En esta rutina d es el valor de la tangente del angulo avanzado
;en cada bucle, o sea la pendiente del vector (X_r,Y_r) respecto al anterior (xr,yr).
;El avance maximo pues, sera de 90 grados cuando d=infinito.
;El sentido de giro depende del signo de d.
;---------------------------------------------------------------------------------
ElseIf MouseButton(2)
xr=X_r:yr=Y_r ;Vector director del radio (distancia del
;centro al objeto)=(x,y)->(x+xr,y+yr)
xa=yr*d:ya=-xr*d ;(xa,ya) es un vector normal al (xr,yr)
;pero con el modulo multiplicado por la
;constante preestablecida d.
xold=x:yold=y
x=MouseX():y=MouseY() ;Actuales coordenadas del centro
DisplayTransparentSprite(0,x,y);draw our mouse pointer just here
Gosub draw;<--Draw on buffer
FlipBuffers();<--swap buffers
DisplaySprite(1,xold,yold);<--restore the old sprite background
GrabSprite(1,x,y,SW,SH,0);<--and save the new one
Gosub draw;<--Draw on the other buffer
X_r+(ya-yr)*2/c:Y_r+(xr-xa)*2/c ;El vector director (xr-xa,yr-ya)
;es la hipotenusa del triangulo
;(0,0)-(xr,yr)-(xa,ya).
;(ya-yr,xr-xa) es por tanto su normal.
;(NOTA:con (yr+ya,-xa-xr) se invierte
;el sentido del giro.)
;Se reduce dicha normal multiplican-
;dola por 2/c, y finalmente se tras-
;lada el vector director obtenido
;al punto item (xr,yr) obteniendo
;un nuevo (X_r,Y_r).
;(NOTA:c es hallada mediante la aplicacion
;del teorema de pitagoras y la propor-
;cionalidad de triangulos, igual que k).
ExamineMouse()
;NOTA: En esta otra rutina, mas compleja que la anterior, el valor de d
;corresponderia a una funcion trigonometrica que seria la longitud, en el
;eje de ordenadas, desde el origen de coordenadas hasta el punto de corte
;con la recta normal, tomada esta desde el extremo (u origen) del ángulo,
;a la que une origen con extremo del ángulo.
;Por tanto, entre 0 y 90 grados d está entre 0 y 1 (0 y -1 si se toma desde el origen),
;y de 90 a 180 d pasa de 1 a infinito (-1 a -infinito si se toma desde el origen).
;---------------------------------------------------------------------------------
EndIf
Return
text:
StartDrawing(ScreenOutput())
BackColor(0,0,0):FrontColor(255,100,240)
Locate(#RX/2-150,#RY/2-20)
DrawText("Push LMB for circle algorithm 1, RMB for circle algorithm 2")
Locate(#RX/2-100,#RY/2+30)
DrawText("Left CTRL key to exit")
StopDrawing()
Return
draw:
StartDrawing(ScreenOutput());<--Draw on the second buffer
Plot(x+xr,y+yr,$c8faff)
StopDrawing()
Return