hola Leonardo,
lo 1º disculpas por la tardanza, pero llevo un par de dias de perros [callejeros, no de esos de
chimenea ...] y no he podido meterle mano casi. Igualmente disculpas por la indefinicion en mi
consulta.
se trata de hallar los puntos de interseccion de 2 circunferencias secantes o tangentes
aunque es un rollo y te lo puedes saltar, te comento un 'poco' el motivo inicial de todo esto, [ que
ademas seguro que tiene formas mas 'propias' y directas de hacerlo, aunque como en el fondo no deja
de ser un ejercicio de 'indagacion', pues tampoco pasa mucho por seguir un poco ..]
'-----
estudiando un poco la manipulacion de graficos, imagenes, etc, en windows forms, me ha dado por
intentar 'animar' palitos/lineas. En este caso se trata de conseguir el efecto de una articulacion
(bueno seria de muchas, pero hecha una hechas todas, creo), por ej. un brazo
P0 o-------------------o P1
brazo \
\ antebrazo
\
o P2
.- para ello tendriamos 3 puntos:
hombro [P0], codo [P1] y muñeca [P2]
.- sobre los que girarian 2 segmentos:
brazo [P0->P1] y antebrazo [P1->P2]
.- el 1er segmento se correspoderia con el radio de la circunferencia con centro en el hombro (P0).
Este punto [en este movimiento] seria fijo.
.- el 2º segmento se corresponderia con el radio de la circunferencia con centro en el codo (P1), y
en este caso [y salvo que este escayolado :-)] evidentemente el punto/codo podria estar en cualquier
punto de la circunferencia con centro en el hombro
.- por ultimo este 2º segmento, o mejor dicho, el 3er punto (P2), correspondiente a la muñeca podria
moverse por cualquier punto del plano siempre y cuando su distancia al punto P1 siempre fuese la
misma [en realidad estariamos hablando de un contorsionista], es decir, que el segmento P1->P2
siempre estuviese unido al P0->P1 en el punto P1 y por supuesto mantteniendo las longitudes de ambos
segmentos
.- siendo asi, cualquier movimiento del punto P1 afectaria a la posicion de P2
.- y a la inversa, salvo que P2 se moviese por los puntos de la circunferencia con centro en P1
(codo) y radio P1->P2. De no ser asi, cualquier desplazamiento de la muñeca provocara el movimiento
del codo
en cualquier caso parece claro que la circunferencia con centro en el hombro (P0) y la que tendria
el centro en la muñeca (P2) y radio P1->P2 siempre tendrian que tener al menos un punto en comun
(P1), el cual podria ser:
a) el punto de tangencia en el caso de que ambas circunferencias fuesen tangentes (brazo estirado o
totalmente plegado)
b) uno de los 2 puntos de interseccion de las 2 circunferencias secantes que se formarian al plegar
el brazo en casi cualquier posicion/angulo
c) caso aparte seria para la misma longitud de brazo y antebrazo (las 2 circ. iguales)
'----------
en fin, que este seria el motivo causante de los desaguisados [tanto de programacion como de
matematicas] que expongo a continuacion
volviendo a tus ej. he hecho esta adaptacion un tanto libre de tus funciones para obtener los
resultados de una ecuacion de 2º grado:
' Para ecuacion de 2º grado que puede ser:
' completa [a^2 + bx + c = 0] o incompleta
' en sus 2 versiones [a^2 + bx = 0] o [a^2 + c = 0]
' En cualquier caso, el coeficiente que falte hay que
' pasarselo como 0 y en su posicion.
' Basada en funciones de Leonardo Azpurua
' [27/06/08]
'
Public Function Ecuacion2doGrado( _
ByVal a As Double, _
ByVal b As Double, _
ByVal c As Double) As Double()
'
Dim x1, x2 As Double
'
If a = 0 Then
MsgBox("La ecuacion no es de 2º grado.")
Return Nothing
ElseIf b = 0 Then
If c = 0 Then
' esta solucion me la estoy inventando a falta
' de repasar un poco de mates. Sorry ...
'
x1 = Sqrt(1 / a)
x2 = -(Sqrt(1 / a))
Else
x1 = Sqrt(-c / a)
x2 = -(Sqrt(-c / a))
End If
ElseIf c = 0 Then
x1 = 0
x2 = -b / a
Else
x1 = ((-b) + Sqrt((b ^ 2) - (4 * a * c))) / (2 * a)
x2 = ((-b) - Sqrt((b ^ 2) - (4 * a * c))) / (2 * a)
End If
Dim xs() As Double = {x1, x2}
Return xs
End Function
y esta seria una prueba, aun a medias, para obtener, por un lado los puntos de interseccion de dos
circunferencias secantes, y por otro un string con el desarrollo y las explicaciones mas o menos
completas de todos los pasos con sus formas y valores en cada paso
seguramente es muy mejorable y haya mas de una burrada (hacia mas de 20 años que no tocaba apenas
las mates, y eso se nota en la neurona ..), aparte de que como digo aun esta incompleto, pero que
mas o menos se ve por donde va
(disculpas por la extension del codigo, pero la mayoria se debe al string con la explicacion, que al
fin y al cabo sirven a la vez para comentar el codigo. Tambien esta un poco estirado aposta para
dejarlo un poco mas claro visualmente.
Public Function Circsecantes( _
ByVal P1 As PointF, _
ByVal P2 As PointF, _
ByVal R1 As Double, _
ByVal R2 As Double, _
ByRef msj As String) As PointF()
msj = "Problema:" & vbCrLf & vbCrLf & _
"Hallar puntos de intersección de dos circunferencias" _
& vbCrLf & "secantes teniendo sus centros y sus radios."
'
msj = msj & vbCrLf & vbCrLf & _
".Circunferencia 1:" & vbCrLf & _
" Centro = " & P1.ToString & vbCrLf & _
" Radio = " & R1 & vbCrLf & _
".Circunferencia 2:" & vbCrLf & _
" Centro = " & P2.ToString & vbCrLf & _
" Radio = " & R2
'
msj = msj & vbCrLf & vbCrLf & _
".Ecuaciones de las circunferencias:"
'
msj = msj & vbCrLf & " 1ª) " & _
"(x - " & P1.X & ") ^ 2 + (y - " & _
P1.Y & ") ^ 2 = " & (R1 ^ 2)
'
msj = msj & vbCrLf & vbCrLf & _
" 2ª) (x - " & P2.X & ") ^ 2 + (y - " & P2.Y & _
") ^ 2 = " & (R2 ^ 2)
'
msj = msj & vbCrLf & vbCrLf & _
".Tras desarrollar y restar ambas ecuaciones" & vbCrLf & _
"obtenemos la siguiente ecuacion lineal:"
'
msj = msj & vbCrLf & vbCrLf & " " & _
(2 * (P1.X - P2.X)) & " * x + " & _
(2 * (P1.Y - P2.Y)) & " * y = " & _
((R2 ^ 2) - (R1 ^ 2) + (P1.X ^ 2) - _
(P2.X ^ 2) + (P1.Y ^ 2) - (P2.Y ^ 2))
'
msj = msj & vbCrLf & vbCrLf & _
".Esta ecuacion la usaremos para despejar una" & vbCrLf & _
"de las incognitas y sustituirla en una de las" & vbCrLf & _
"ecuaciones de las circunferencis."
'
' Asignamos una variable a cada coeficiente para aclarar un
' poco su uso en el codigo
'
Dim a, b, c ', d, e, f As Double
'
a = 2 * (P1.X - P2.X)
b = 2 * (P1.Y - P2.Y)
c = R2 - R1 + (P1.X ^ 2) - (P2.X ^ 2) + (P1.Y ^ 2) - (P2.Y ^ 2)
'
' despejamos x
'
msj = msj & vbCrLf & vbCrLf & _
" X = (" & c & " - (" & b & " * Y)) / " & a
'
msj = msj & vbCrLf & vbCrLf & _
".Sustituimos X en la ecuación de la 2ª circunferencia:"
'
msj = msj & vbCrLf & vbCrLf & " " & _
"(((" & c & " - (" & b & " * Y)) / " & a & ") - " & _
P2.X & ") ^ 2 + (y - " & P2.Y & ") ^ 2 = " & (R2 ^ 2)
'
' Y de momento aqui ando liado. Voy a unificar los coeficientes
' para aplicar la funcion para Ecuaciones de 2º grado
'
' lo siguiente es provisional a la espera de llegar al final,
' ahora simplemente devuelve los mismos puntos que le pasamos.
' Es para ir probando el msj sin que te de la tabarra el editor 8-)
'
Dim pfs() As PointF = {P1, P2}
Return pfs
End Function
y para probarlo por ej:
Dim pf() As PointF = PuntosCircSecantes(New PointF(4, 3), _
New PointF(7, 2), 2, 2, msj)
Debug.Print(msj)
bueno, como ves (veis) no exagero mucho al decir que soy un 'pelin' retorcidillo, pero al menos,
aparte de instructivo, resulta bastante entretenido
un saludo y muchas gracias de nuevo (tomo nota de tu ultimo apunte)
Ivan