Visual Basic Foro
Programación => Visual Basic 6 => Mensaje iniciado por: LeandroA en Marzo 24, 2010, 04:06:41 pm
-
hola quiero girar una imagen y me tiene de hijo la función matemática necesito saber dos medias en base a un ángulo que yo le pase, por ejemplo de estas tres imagenes la primera es la original la segunda de la misma imagen rotada 20º y la tercera 45º, bien yo marque por debajo de queda esquina un punto Azul este punto es el que necesito saber en base al ángulo que yo asigne
(http://img185.imageshack.us/img185/605/image11w.png)
si tomamos la tercera como referencia, su izquierda ahora esta 55 pixels (aproximadamente) mas a al derecha y su esquina inferior se elevo unos 28 pixels (aproximadamente) que calculo tengo que hacer para averiguar ese punto (X,Y) marcado con un puntito azul
-
Mmm...yo usaria funciones trigonometricas (seno, coseno) multiplicadas por algo que las "minimize" para obtener las 2 variables, Otra forma se me ocurre usando la simple teoria de la hipotenusa (suma de catetos al cuadrado :P) pero bueno, ahora no dispongo de tiempo, despues intentare plasmarlo en codigo :P
-
Leandro, me parece que deberias dar exacto los valores de la imagen 2 tambien, porque sabiendo una sola, no se podria calcular la formula creo...porque hay que saber que cantidad de "pixeles" que cambio desde la 2 a la 3...y ahi si se podria hacer una formula, porque creo que no es "lineal"..o sea si en 40 grados supongamos que esta en (40,40), en 20 grados esta en (20,20), pero aca no es asi lineal, por eso deberias poner la de la segunda imagen...y asi podes sacar la formula para cualquier graduacion...
saludos.
-
Hola gracias, bueno la verdad que me trae de pelos y no doy como hacerlo, las medidas se me hace dificil pasartelas porque el programa que uso me cambia las medidas originales, voy a poner un gif de lo que quiero hacer, me seria de utilidad si alguien me puede dar un ejemplo utilizando controles "Line"
Se que seguramente hay que usar funciones sin cos tan pi pero soy duro con las matematicas.
(http://img705.imageshack.us/img705/3063/animation1ty.gif)
Saludos.
-
Jaja todo se puede, lo que hay que hacer es sacar la longitud del arco que forma el angulo, y de ahi usarlo como vector para sacar la proyeccion desde nuestro punto de vista ("efecto 3d") y de ahi obtienes los valores X e Y correspondientes (al menos ese es mi punto de vista. Como dije, no dispongo de tiempo (es feriado y no estoy solo ::)) asi que mañana a primera hora trabajare en el tema
-
este es un ejemplo de como hacer un Cubo 3D, cosa que si te das cuenta la puedes modificar para hacerlo a tu manera:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3845&lngWId=1
-
Jeje, leandro, este ejemplo te puede re servir (yo me di por vencido JAJA), miralo y entonces podras usarlo para todo :P (te da hasta los puntos :P)
Cubo en 3D girando + EFECTO Optico- Sin apis (explicacion) (http://foro.elhacker.net/programacion_vb/cubo_en_3d_girando_efecto_optico_sin_apis_explicacion-t235246.0.html)
Lo habia visto hace tiempo, se me ocurrio mostrartelo cuando volvia de la facu :P
igual, me mato la frase:
Lo bueno de estas cosas es que aplicas la matematica qe algun dia aprendiste, y no comprendes porque la aprendiste...
-
Gracias por su colaboración, con el Link de PSC pude hacer algo, pero de todas formas no entendi nada solo fui resumiendo hasta poder hacer lo mas pequeño posible el codigo, y se que se puede mejorar pero como dije antes no entendi nada.
Option Explicit
Const PI180 As Double = 0.01745392 '3,14159265 / 180
Dim Angulo, CSX, CSY As Integer
Dim lLeft As Long
Dim lTop As Long
Dim lWidth As Long
Dim lHeight As Long
Private Sub PosXY(y1 As Double, z1 As Double)
Dim Yy As Double
Dim CosA As Double, CosB As Double
Dim SinA As Double, SinB As Double
CosA = Cos(Angulo * PI180)
SinA = Sin(Angulo * PI180)
CosB = Cos(90 * PI180)
SinB = Sin(90 * PI180)
Yy = 5 / (10 - (CosB + y1 * SinA))
CSX = lLeft + lWidth * ((y1 * CosA)) / 2
CSY = lTop + lHeight * ((y1 * CosB - (CosB * CosA) - z1 * SinB) * Yy)
End Sub
Private Sub Form_Load()
lLeft = 200
lTop = 200
lWidth = 250
lHeight = 250
End Sub
Sub Draw()
Dim xxx, yyy
Dim x, y
Form1.Cls
PosXY -1, -1: xxx = CSX: yyy = CSY:
PosXY 1, -1: Line (xxx, yyy)-(CSX, CSY), vbWhite: x = CSX: y = CSY
PosXY 1, 1: Line (x, y)-(CSX, CSY), vbWhite: x = CSX: y = CSY
PosXY -1, 1
Line (x, y)-(CSX, CSY), vbWhite
Line (CSX, CSY)-(xxx, yyy), vbWhite
End Sub
Private Sub Timer1_Timer()
Angulo = Angulo + 5
Draw
End Sub
-
Aver leandro si esto te sirve, yo tampoco se del tema (jamas vi coordenadas polares o.O) pero uno jugando aprende y aunque sea por equivocacion uno descubre cosas (es la verdad no? muchas cosas se descubrieron asi)
Se necesita un timer, primero pongan Interval en 100 para ver el "efecto" luego en 500 para que lo vean detalladamente
'#########################################
' Para Leandro
' por raul338, idea original por "Jackl007!"
'#########################################
Const PI = 3.141592654
Dim Inter As Integer 'Intervalo del Angulo
Dim Pers As Integer 'Intervalo de la perspectiva
Function AngRad(ByVal a As Double) As Double
'Esta funcion convierte un Angulo Decimal a un angulo en radianes,
'recordar que necesitamos hacer dicho cambio para poder trabajar con los incrementos
'ya que la funcion seno, y coseno recibe en RADIANES
AngRad = (a * PI / 180)
End Function
Private Sub Form_Load()
Inter = 0
Pers = 1
Me.AutoRedraw = True
Me.BackColor = vbBlack
Me.Height = 6180
Me.Width = 6180
Scale (-50, 50)-(50, -50) 'Mi escala, en X y en Y normal
End Sub
Sub Cubo(ByVal R1 As Double, ByVal R2 As Double, ByVal Ang As Double)
Dim a, i As Integer
Dim xA, xB, yA, yB As Double ' Las coordenadas de los puntos
Dim xC, xD, yC, yD As Double ' del cubo
a = -Ang + 180 'inclinacion entre cada radio
'(Raul338:) No se porque, pero con esa cuenta me dio perfecto para el punto de vista de Leandro
'Cambiamos a sistema de coordenadas polares
xA = R1 * Cos(AngRad(a))
yA = (R2 * Sin(AngRad(a)) + R1 / 2) '/ 2
yA = yA - yA * Sin(AngRad(a)) / 2
Me.CurrentX = xA
Me.CurrentY = yA
Me.Print "A"
xB = R1 * Cos(AngRad(a))
yB = (R2 * Sin(AngRad(a)) - R1 / 2)
Me.CurrentX = xB
Me.CurrentY = yB
Me.Print "B"
xC = R1 * Cos(AngRad(a + 180))
yC = (R2 * Sin(AngRad(a + 180)) - R1 / 2) '* 2
Me.CurrentX = xC
Me.CurrentY = yC
Me.Print "C"
xD = R1 * Cos(AngRad(a + 180))
yD = (R2 * Sin(AngRad(a + 180)) + R1 / 2)
yD = yD + yD * Sin(AngRad(a)) / 2
Me.CurrentX = xD
Me.CurrentY = yD
Me.Print "D"
Line (xA, yA)-(xB, yB), &H1B1B1B ' Lado izquierdo
Line (xB, yB)-(xC, yC), &HFFAAAA ' Lado de abajo
Line (xC, yC)-(xD, yD), &HAAFFAA ' Lado izquierdo
Line (xD, yD)-(xA, yA), &HAAAAFF ' Lado de arriba
End Sub
Private Sub Timer1_Timer()
Cls
Me.Print Inter & "�" & vbCrLf; "P: " & Pers
' Parametros
' Primer radio, "ancho de la caja"
' Segundo radio, "Perspectiva" desde donde se ve (mas alto el numero, mas arriba)
' Ultimo parametro, angulo de desplazamiento
Cubo 30, Pers, Inter
Inter = Inter + 10
If Inter > 90 Then
Pers = Pers + 2
If Pers = 11 Then Pers = 1
Inter = 0
End If
End Sub
Miren a la hora que posteo, no, no es nada raro, estoy en la argentina y no tengo sueño y mañana me toman un parcial y aca estoy....tomando las viejas rendas con vb6 8) (3:33 am xD, esperando que sean las 3:38 (?))
Leandro: deberias arreglar el tema de los tipos de caracteres, en la base de datos deberias usar encoding utf o latin, el mismo que aparesca aca en el foro, es horrible estar cambiando esos signos raros ("?" dentro de rombos) a cada rato con cada edicion jaja
-
Siguiendo investigando, logre hacer que una foto paresca 3d, pero por alguna razon me sale al revez :'(
Gracias a Leandro (ironicamente de casualidad, estoy usando su codigo modificandolo para ayudarlo jaja) Rotar graficos e imagenes con Gdi+ (http://www.recursosvisualbasic.com.ar/htm/listado-api/221-rotar-graficos-imagenes-con-PlgBlt.htm)
En un form aparte, pongan un Slider y 2 pictures box del mismo tamaño (en lo posible grandes)
Solo hace falta un timer y un picture (picture2) y una foto chica "imagen.jpg" en la carpeta de la app
Option Explicit
Const PI = 3.141592654
Private Declare Function SetStretchBltMode Lib "gdi32" ( _
ByVal hdc As Long, _
ByVal nStretchMode As Long) As Long
Private Declare Function PlgBlt Lib "gdi32.dll" ( _
ByVal hdcDest As Long, _
lpPicture1int As Picture1INTAPI, _
ByVal hdcSrc As Long, _
ByVal nXSrc As Long, _
ByVal nYSrc As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hbmMask As Long, _
ByVal xMask As Long, _
ByVal yMask As Long) As Long
Private Type Picture1INTAPI
x As Long
y As Long
End Type
Dim PtList(3) As Picture1INTAPI
Dim inter As Integer
Private Sub Command1_Click()
Form1.Show
Me.Hide
End Sub
Private Sub Form_Load()
With Picture2
.AutoSize = True
.Visible = False
.AutoRedraw = True
.ScaleMode = vbPixels
.Picture = LoadPicture(App.Path & "\imagen.jpg")
End With
Call Draw
End Sub
Function AngRad(ByVal a As Double) As Double
'Esta funcion convierte un Angulo Decimal a un angulo en radianes,
'recordar que necesitamos hacer dicho cambio para poder trabajar con los incrementos
'ya que la funcion seno, y coseno recibe en RADIANES
AngRad = (a * PI / 180)
End Function
Sub DoRedraw(ByVal R1 As Double, ByVal R2 As Double, ByVal Ang As Double, Optional DespX As Integer = 50, Optional DespY, Optional Zoom As Integer = 2)
Dim a, i As Integer
Dim xA, xB, yA, yB As Double ' Las coordenadas de los puntos
Dim xC, xD, yC, yD As Double ' del cubo
' Aca por razones misteriosas, no hace falta este calculo
' a = -Ang + 180
'(Raul338:) No se porque, pero con una foto no hace diferencia, en cambio si lo
' cambiabamos al anterior si se cambiaba la "ilusion optica"
xA = (R1 * Cos(AngRad(Ang)) + DespX) * Zoom
yA = ((R2 * Sin(AngRad(Ang)) + R1 / 2) + DespY) * Zoom
xB = (R1 * Cos(AngRad(Ang)) + DespX) * Zoom
yB = ((R2 * Sin(AngRad(Ang)) - R1 / 2) + DespY) * Zoom
xC = (R1 * Cos(AngRad(Ang + 180)) + DespX) * Zoom
yC = ((R2 * Sin(AngRad(Ang + 180)) - R1 / 2) + DespY) * Zoom
xD = (R1 * Cos(AngRad(Ang + 180)) + DespX) * Zoom
yD = ((R2 * Sin(AngRad(Ang + 180)) + R1 / 2) + DespY) * Zoom
'Cambiamos a sistema de coordenadas polares
' Derecha abajo
PtList(0).x = xC
PtList(0).y = yC
' Izquierda abajo
PtList(1).x = xB
PtList(1).y = yB
' Dercha arriba
PtList(2).x = xD
PtList(2).y = yD
' El cuarto punto se calucla automaticamente (segun MSDN)
Cls
'opcional-- suaviza un poco cuando esta la figura en posocion recta
SetStretchBltMode Me.hdc, vbPaletteModeNone
'api que rota la imagen
Call PlgBlt(Me.hdc, PtList(0), Picture2.hdc, 0, 0, Picture2.ScaleWidth, _
Picture2.ScaleHeight, 0, 0, 0)
End Sub
Sub Draw()
DoRedraw 30, 5, inter * 5, 50, 30, 4
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
End
End Sub
Private Sub Timer1_Timer()
inter = inter + 1
If inter = 72 Then inter = 1
Draw
End Sub
(http://img210.imageshack.us/img210/5198/sinttulodv.th.jpg) (http://img210.imageshack.us/img210/5198/sinttulodv.jpg)
Ya salio bien 8) 8) para el que lo quiera, citarme como autor ;D
-
Gracias Raul por tu tiempo pero hay un problema fijate que es una rotación 3D osea forma un trapezoide en determinado momento el lado lateral izquierdo es menor al derecho, para forma grafica voy autilizar otro metodo ya que con PlgBlt no se puede hacer esa figura. el codigo que resumi del que me paso xmbeat hace eso. pero bueno supongo que puede mejorarse. no me cierra mucho esta linea Yy = 5 / (10 - (CosB + y1 * SinA))
Saludos.
-
Por eso es una simulacion 3d, estuve probando calculos para lograr ese efecto, pero no me salia incluso con el cuadrado dibujado.
Podrias decirme que metodo utilizaras asi tambien practico y veo que se puede hacer :)
Vi el codigo de xmbeat pero muy bien no lo entendi, entendi mejor el otro con el que trabaje
El feo de la foto soy yo con una amiga jaja
-
Bueno lea mira esto es lo q pude hacer... estaba bueno el problema gracias
(+) Agrega un text1.text
(+) Dos Label label1 y label2
(+) Un boton Command1
(+) Un timer con intervalo 1000 osea 1segundo
Pinta de color negro el fondo del formulario
Const PI180 As Double = 0.01745392 '3,14159265 / 180
Private Sub Command1_Click()
Call DibujoCuadrado(Text1.Text) ' el valor de los angulos en grado
End Sub
Sub DibujoCuadrado(Angulo As Double)
Form1.Cls
Dim X0, Y0, X1, Y1, X2, Y2, X3, Y3 As Integer ' PO,P1,P2,P3 donde P(X,Y) forman los cuatro puntos del cuadrado
X0 = 2500 - (1000 * Cos(Angulo * PI180)) ' Para pasar de radianes a grados multiplicamos por Pi y dividimos por 180�
Y0 = 5000 - (1000 * Sin(Angulo * PI180))
X1 = 2500 + (1000 * Cos(Angulo * PI180))
Y1 = 5000 + (1000 * Sin(Angulo * PI180))
Line (X0, Y0)-(X1, Y1), vbRed
Label1.Caption = "X0 :" & X0 & vbCrLf & "Y0 :" & Y0 & vbCrLf & "X1 :" & X1 & vbCrLf & "Y1 :" & Y1
X2 = 2500 - (1000 * Cos(Angulo * PI180)) ' Para pasar de radianes a grados multiplicamos por Pi y dividimos por 180�
Y2 = 2000 - (1000 * Sin(Angulo * PI180))
X3 = 2500 + (1000 * Cos(Angulo * PI180))
Y3 = 2000 + (1000 * Sin(Angulo * PI180))
Line (X2, Y2)-(X3, Y3), vbRed
Label2.Caption = "X2 :" & X2 & vbCrLf & "Y2 :" & Y2 & vbCrLf & "X3 :" & X3 & vbCrLf & "Y3 :" & Y3
Line (X0, Y0)-(X2, Y2), vbRed
Line (X1, Y1)-(X3, Y3), vbRed
End Sub
Private Sub Timer1_Timer()
Text1 = Text1 + 5
Call DibujoCuadrado(Text1) ' el valor de los angulos en grado
End Sub(http://beto123456789.webcindario.com/cuadrado.jpg)
BIOGRAFÍA CITADA:
http://es.wikipedia.org/wiki/Trigonometr%C3%ADa (http://es.wikipedia.org/wiki/Trigonometr%C3%ADa)
-
Bueno ya estaria solucionado, finalmente esto es "algo" de lo que queria hacer.
un timer un picture con una imagen (pequeña)
Option Explicit
Private Declare Function StretchBlt Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function SetStretchBltMode Lib "gdi32.dll" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
Private Sub Form_Load()
Picture1.ScaleMode = 3
Picture1.AutoSize = True
Picture1.AutoRedraw = True
Me.ScaleMode = 3
Me.AutoRedraw = True
Timer1.Interval = 10
End Sub
Sub DrawPerspective(DestHdc As Long, ByVal lLeft As Long, ByVal lTop As Long, ByVal lWidth As Long, ByVal lHeight As Long, SrcDC As Long, ByVal Angle As Double)
Dim CosA As Double, CosB As Double
Dim SinA As Double, SinB As Double
Dim PT(3) As POINTAPI
Dim i As Long
Dim lW As Long
Dim FirstH As Long
Dim LastH As Long
Dim PercentY As Single
Const PI180 As Double = 0.01745392 '3,14159265 / 180
CosA = Cos(Angle * PI180)
SinA = Sin(Angle * PI180)
CosB = Cos(90 * PI180)
SinB = Sin(90 * PI180)
PT(0).x = lLeft + lWidth * CosA / 2
PT(0).y = lTop + lHeight * ((CosB - (CosB * CosA) - SinB) * (5 / (10 - CosB + SinA)))
PT(1).x = PT(0).x
PT(1).y = lTop + lHeight * ((CosB - (CosB * CosA) + SinB) * (5 / (10 - CosB + SinA)))
PT(2).x = lLeft + lWidth * -CosA / 2
PT(2).y = lTop + lHeight * ((-CosB - (CosB * CosA) + SinB) * (5 / (10 - CosB - SinA)))
PT(3).x = PT(2).x
PT(3).y = lTop + lHeight * ((-CosB - (CosB * CosA) - SinB) * (5 / (10 - CosB - SinA)))
'SetStretchBltMode DestHdc, vbPaletteModeNone
lW = PT(2).x - PT(0).x
FirstH = PT(2).y - PT(3).y
LastH = PT(1).y - PT(0).y
For i = 0 To lWidth
PercentY = ((FirstH - LastH) * i / lWidth)
StretchBlt DestHdc, PT(2).x + (-lW * i / lWidth), PT(3).y + PercentY / 2, 1, FirstH - PercentY, SrcDC, i, 0, 1, lHeight, vbSrcCopy
Next
'Line (PT(0).x, PT(0).y)-(PT(1).x, PT(1).y), vbWhite
'Line (PT(1).x, PT(1).y)-(PT(2).x, PT(2).y), vbWhite
'Line (PT(2).x, PT(2).y)-(PT(3).x, PT(3).y), vbWhite
'Line (PT(3).x, PT(3).y)-(PT(0).x, PT(0).y), vbWhite
End Sub
Private Sub Timer1_Timer()
Static Angulo As Double
Angulo = Angulo + 5
Me.Cls
DrawPerspective Me.hdc, 150, 150, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hdc, Angulo
Me.Refresh
End Sub
Leandro: deberias arreglar el tema de los tipos de caracteres, en la base de datos deberias usar encoding utf o latin, el mismo que aparesca aca en el foro, es horrible estar cambiando esos signos raros ("?" dentro de rombos) a cada rato con cada edicion jaja
vi en una parte del foro que daba esa opción pero no quise meter mano para no meter la pata despues me ago un backup y pruebo.
Saludos y gracias a todos.
-
Impresionante leandro, te pasas :P
Ya puse el codigo para que paresca 3d el cuadrado negro giratorio (se agranda el lado que esta mas cerca) pero no pude implementarlo para las imagenes, de todas formas, fue bueno intentarlo. Ahora, a seguir experimentando :P
-
Te quedo muy bueno leaa te felicitoo ..... :D