Foros del Web » Programación para mayores de 30 ;) » Programación General »

Como graficar en el eje de coordenadas una funcion

Estas en el tema de Como graficar en el eje de coordenadas una funcion en el foro de Programación General en Foros del Web. Hola mi nombre es Alexandra,necesito ayuda sobre como realizar gráficos en dos dimensiones en visual Basic, ya que debo presentar mi proyecto de fin de ...
  #1 (permalink)  
Antiguo 04/09/2004, 12:47
 
Fecha de Ingreso: septiembre-2004
Mensajes: 3
Antigüedad: 19 años, 8 meses
Puntos: 0
Como graficar en el eje de coordenadas una funcion

Hola mi nombre es Alexandra,necesito ayuda sobre como realizar gráficos en dos dimensiones en visual Basic, ya que debo presentar mi proyecto de fin de carrera sobre software para métodos numéricos, tengo un manual que me ayuda pero no me funcionan correctamente las funciones como line, etc.
Te pido que me ayudes de ser posible, con ejemplos o alguna dirección que me permita conocer la forma correcta de aplicar las funciones para realizar los gráficos. Por favor es urgente, si puedes ayúdame. Te lo agradeceré mucho.
  #2 (permalink)  
Antiguo 04/09/2004, 20:30
 
Fecha de Ingreso: noviembre-2003
Ubicación: Mexico
Mensajes: 1.081
Antigüedad: 20 años, 5 meses
Puntos: 7
necesariamente debe ser con VB???
porque les siguen enseñando eso???
en c/c++ lo puedes hacer con el winApi (windows.h), me imagino que en VB tambien
  #3 (permalink)  
Antiguo 10/09/2004, 17:36
 
Fecha de Ingreso: septiembre-2004
Mensajes: 3
Antigüedad: 19 años, 8 meses
Puntos: 0
que hay nadie sabe graficar con vb6
  #4 (permalink)  
Antiguo 10/09/2004, 18:54
Avatar de GeoAvila
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Antigua Guatemala
Mensajes: 4.032
Antigüedad: 20 años, 4 meses
Puntos: 53
claro que si se puede no soy experto en el area pero te puedo enviar un par de samples enviame un mensaje y te envio el ejemplo...

nos vemos..
__________________
* Antes de preguntar lee las FAQ, y por favor no hagas preguntas en las FAQ
Sitio http://www.geoavila.com twitter: @GeoAvila
  #5 (permalink)  
Antiguo 10/09/2004, 18:55
Avatar de GeoAvila
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Antigua Guatemala
Mensajes: 4.032
Antigüedad: 20 años, 4 meses
Puntos: 53
es Decir Enviame un E-mail
__________________
* Antes de preguntar lee las FAQ, y por favor no hagas preguntas en las FAQ
Sitio http://www.geoavila.com twitter: @GeoAvila
  #6 (permalink)  
Antiguo 13/09/2004, 09:48
Avatar de Beakdan  
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 22 años, 4 meses
Puntos: 7
Malexandrapc:
Hola. Supongo que el ejemplo con la API que te envié no te sirvió de mucho... Tenía unas horas libres el fin de semana, así que hice este programita, que tal vez te pueda servir. Grafica ecuaciones matemáticas, siempre que las pongas con la sintaxis que usarías en VB para programar dicha ecuación. Si te sientes más cómoda con JS, entonces, le cambias el modo al control que utiliza y usas la sintaxis de JS. El control es Microsoft Script Control (msscript.ocx). Yo prefiero incluirlo como referencia, pero si lo deseas simplemente inserta el control y modifica el código para que así funcione. Lo que tienes que hacer:

1.- En un nuevo proyecto, agrega una referencia a Microsoft Script Control 1.0, con el menú Proyecto/Referencias. Debe de estar en tu sistema, pero si no, descárgalo desde el sitio de Microsoft, es gratuito y es muy pequeño.

2.- En el formulario del proyecto, agrega:
i) Un Botón (command1)
ii) Una etiqueta (label1)
iii) Un cuadro de texto (Text1)
iv) Un Timer (Timer1) y
v) Un ComboBox (Combo1)

3.- Cambia la propiedad index de Label1 y Text1 a cero.

Y ahora, copia y pega el siguiente código.
Código:
Option Explicit

Private Enum EnumErrorSolve
    ESOK
    ESInfinit
    ESArgInvalid
    ESOverFlow
End Enum

Private Const ErrorSolve As Long = &HFFFFFFF
Private Const FormPad    As Long = 10

Private m_lXValReal      As Double
Private m_lYValReal      As Double
Private m_lXOrigin       As Long
Private m_lYOrigin       As Long
Private m_lArrTxtVal(0 To 13) As String
Private m_bAllowChange As Boolean

Private Sub Combo1_Click()
Dim sValues As Variant
Dim i       As Long

    m_bAllowChange = False
    sValues = Split(m_lArrTxtVal(Combo1.ListIndex), ",")
    'Combo1.Text = "Combo1"
    For i = 0 To 5
        Text1(i).Text = sValues(i)
    Next i
    m_bAllowChange = True
    
    Timer1.Enabled = True
End Sub

Private Sub Command1_Click()
Dim i            As Long
Dim j            As Long
Dim lCurrentY    As Long
Dim lErResult    As EnumErrorSolve
Dim sEquations() As String
Dim lColor       As Variant

'Por si se hemos olvidado contemplar algo
On Error Resume Next

    'Si no hay nada que hacer...
    If Not Combo1.Text <> "" Then Exit Sub
    
    'Se prodrían hacer verificaciones más complejas, para
    'asegurarnos de que realmente se tiene una(s) funcion(es)
    'pero eso se quedará de tarea...
    
    'Usaremos un color aleatorio (de entre la siguiente lista)
    lColor = Array(&HC0C0&, vbRed, &HC000&, vbBlue, vbMagenta, &HC0C000)
    Randomize (Timer)
    Me.Cls
    'Separamos las ecuaciones
    sEquations = Split(Combo1.Text, ";")
    For j = LBound(sEquations) To UBound(sEquations)
        Me.ForeColor = lColor(Int(Rnd() * 7))
        For i = 0 To Me.ScaleWidth
            'Solicitamos f(x)
            lErResult = Solve(sEquations(j), CDbl(i - m_lXOrigin) * m_lXValReal, lCurrentY)
            If lErResult = ESOK Then    'No hubo errores
                If i = 0 Then
                    Me.CurrentX = 0
                    Me.CurrentY = lCurrentY
                Else
                    Me.Line -(i, lCurrentY)
                End If
            Else    'Si la expresión causa un error
                Do
                    If i <= Me.ScaleHeight Then
                        i = i + 1
                    Else
                        Exit Do
                    End If
                Loop Until Solve(sEquations(j), CDbl(i - m_lXOrigin) * m_lXValReal, lCurrentY) = ESOK
                Me.CurrentX = i
                Me.CurrentY = lCurrentY
            End If
        Next i
    Next j
 End Sub

Private Sub Form_Load()

    'Usamos pixels en lugar de twips
    Me.ScaleMode = vbPixels
    'Me.BackColor = vbWindowBackground
    Me.Caption = "Hypatia"
    
    'Maximizamos la ventana
    Me.WindowState = vbMaximized
    
    'Mostramos la ventana. Esto es para poder calcular las
    'distancias de las lineas de la cuadrícula. Si no lo
    'hacemos, los valores de las dimensiones del form,
    'no reflejan el valor actual (maximizado), sino los valores del form
    'en el diseño.
    Me.Show
    
    Timer1.Enabled = False
    Timer1.Interval = 100
    
    With Command1
        .Left = 440: .Top = 8
        .Height = 25: .Width = 120
        .Caption = "Graficar Ecuación"
    End With
    
    With Text1(0)
        .Alignment = vbRightJustify
        .Width = 60: .Left = 80
        .Height = 21: .Top = 50
        .Text = "-10"
    End With
    
    Load Text1(1)
    With Text1(1)
        .Top = Text1(0).Top + Text1(0).Height + 4
        .Text = -8: .Visible = True
    End With
    
    Load Text1(2)
    With Text1(2)
        .Top = Text1(1).Top + Text1(1).Height + 4
        .Text = "1": .Visible = True
    End With
    
    Load Text1(3)
    With Text1(3)
        .Top = Text1(2).Top + Text1(2).Height + 4
        .Text = "1": .Visible = True
    End With
    
    Load Text1(4)
    With Text1(4)
        .Top = Text1(3).Top + Text1(3).Height + 4
        .Text = "20": .Visible = True
    End With

    Load Text1(5)
    With Text1(5)
        .Top = Text1(4).Top + Text1(4).Height + 4
        .Text = "16": .Visible = True
    End With

    With Label1(0)
        .AutoSize = True
        .BackStyle = vbTransparent
        .Alignment = vbRightJustify
        .Top = 54
        .Left = 76 - .Width
        .Caption = "Inicio X:"
    End With
    
    Load Label1(1)
    With Label1(1)
        .Top = Text1(1).Top + 4
        .Caption = "Inicio Y:"
        .Visible = True
    End With

    Load Label1(2)
    With Label1(2)
        .Top = Text1(2).Top + 4
        .Caption = "Escala X:"
        .Visible = True
    End With
    
    Load Label1(3)
    With Label1(3)
        .Top = Text1(3).Top + 4
        .Caption = "Escala Y:"
        .Visible = True
    End With
    
    Load Label1(4)
    With Label1(4)
        .Top = Text1(4).Top + 4
        .Caption = "Divisiones X:"
        .Visible = True
    End With

    Load Label1(5)
    With Label1(5)
        .Top = Text1(5).Top + 4
        .Caption = "Divisiones Y:"
        .Visible = True
    End With
    
    LoadUnloadLabels
    DrawGrid

    'Estas son algunas ecuaciones de ejemplo, que tienen propiedades interesantes.
    With Combo1
        .Left = 8: .Top = 8
        .Width = 420
        .AddItem "X; 2 * X; 3 * X; X / 2; X / 3"
        m_lArrTxtVal(0) = "-11,-8,1,1,22,16"
        .AddItem "Sqr(x)"
        m_lArrTxtVal(1) = "0,-5,250,5,20,16"
        .AddItem "Log(x)"
        m_lArrTxtVal(2) = "0,-4,50,1,20,13"
        .AddItem "(2 * X) ^ 2"
        m_lArrTxtVal(3) = "-11,0,1,10,22,16"
        .AddItem "((2 * X) ^ 2) / (X - 1)"
        m_lArrTxtVal(4) = "-9,-70,1,10,22,16"
        .AddItem "(2 * (X ^ 3)) - X"
        m_lArrTxtVal(5) = "-3,-1,0.3,0.1,20,20"
        .AddItem "(X + 2) / ((X ^2) - (2 * X))"
        m_lArrTxtVal(6) = "-3,-16,0.5,2,20,16"
        .AddItem "(2 * X) / ((X + 3) ^ 2)"
        m_lArrTxtVal(7) = "-8,-60,0.5,5,20,16"
        .AddItem "((X ^ 2) - X + 1) / ((X ^ 2) + 1)"
        m_lArrTxtVal(8) = "-32,0,4,0.2,16,10"
        .AddItem "Abs(X * (X + 2) * (X - 2))"
        m_lArrTxtVal(9) = "-4,-1,0.4,0.5,20,16"
        .AddItem "Sin(x)"
        m_lArrTxtVal(10) = "-7,-1,1,0.1,14,20"
        .AddItem "Atn(x)"
        m_lArrTxtVal(11) = "-10,-2,1,0.2,20,20"
        .AddItem "Sqr(((4 * (X ^ 2)) + (8 * X) + 16) / 3); -Sqr(((4 * (X ^ 2)) + (8 * X) + 16) / 3); (2 * (X + 1)) / Sqr(3); -(2 * (X + 1)) / Sqr(3)"
        m_lArrTxtVal(12) = "-26,-20,2,2,26,20"
        .AddItem "Sqr(1 - (X ^ 2)); -Sqr(1 - (X ^ 2));Sqr((2/3) - (2 *(X ^ 2)) / 3); -Sqr((2/3) - (2 *(X ^ 2)) / 3)"
        m_lArrTxtVal(13) = "-2,-1,0.1,0.1,30,20"
        .Text = ""
    End With
    m_bAllowChange = True
End Sub
Abajo continúa el código...
  #7 (permalink)  
Antiguo 13/09/2004, 10:04
Avatar de Beakdan  
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 22 años, 4 meses
Puntos: 7
Continúa...
Código:
Private Sub LoadUnloadLabels()
'Puesto que con VB no se tiene un método para
'dibujar texto en una coordenada específica,
'usamos labels para obtener esta funcionalidad.
'Cargamos y descargamos los label según se requieran

Dim nLabels     As Long
Dim i           As Long

    nLabels = CLng(Text1(4).Text) + CLng(Text1(5).Text) + 7
    If Label1.UBound > nLabels Then
        For i = (nLabels + 1) To Label1.UBound
            Unload Label1(i)
        Next i
    End If
    
    If Label1.UBound < nLabels Then
        For i = (Label1.UBound + 1) To nLabels
            Load Label1(i)
            With Label1(i)
                .Alignment = vbLeftJustify
                .Caption = ""
                .ForeColor = vbHighlight
                .Visible = True
            End With
        Next i
    End If
End Sub

Private Sub DrawGrid()
Dim i               As Long
Dim iCtrl           As Long
Dim x               As Long
Dim y               As Long
Dim lXDivition      As Long
Dim lYDivition      As Long

    'Al cambiar la propiedad autoredraw a True,
    'le indicamos a visual basic que esta parte del
    'gráfico se mantendrá en memoria. Luego cambiamos
    'la propiedad nuevamente a false. De este modo, evitamos
    'tener que dibujar la rejilla cada vez dibujamos
    'la curva de la ecuación
    
    Me.AutoRedraw = True
    Me.Cls
    
    iCtrl = 6
    
    'espaciado entre líneas verticales
    lXDivition = (Me.ScaleWidth - (FormPad * 2)) \ CStr(Text1(4).Text)
    m_lXValReal = CStr(Text1(2).Text) / lXDivition
    
    'espaciado entre líneas horizontales
    lYDivition = (Me.ScaleHeight - (FormPad * 3)) \ CStr(Text1(5).Text)
    m_lYValReal = CStr(Text1(3).Text) / lYDivition

    'Necesitamos encontrar la posición del punto
    'de origen de la escala de usuario en coordenadas de pantalla
    m_lXOrigin = (((0 - CLng(Text1(0).Text)) / CSng(Text1(2).Text)) * lXDivition) + FormPad
    m_lYOrigin = Me.ScaleHeight - (((0 - CLng(Text1(1).Text)) / CSng(Text1(3).Text)) * lYDivition) - (FormPad * 2)
    
    Me.ForeColor = vb3DShadow
    Me.DrawStyle = vbDot
    
    'Lineas verticales del gráfico
    For i = 0 To CStr(Text1(4).Text)
        'calculamos la posición en X
        x = FormPad + (i * lXDivition)
        'Trazamos la línea
        Me.Line (x, 0)-(x, Me.ScaleHeight)
        
        With Label1(iCtrl)
            'ocultamos el control antes de actualizar sus
            'propiedades. Esto acelera un poco el proceso.
            .Visible = False
            If m_lYOrigin < 0 Then
                .Top = 1
            ElseIf m_lYOrigin > (Me.ScaleHeight - ((FormPad * 2) + 1)) Then
                .Top = Me.ScaleHeight - ((FormPad * 2) - 1)
            Else
                .Top = m_lYOrigin + 1
            End If
            .Left = x + 1
            .Caption = Format(CLng(Text1(0).Text) + (i * Text1(2)), "###,##0.000")
            .Visible = True
        End With
        iCtrl = iCtrl + 1
    Next i
    
    'Lineas horizontales del gráfico
    For i = 0 To CStr(Text1(5).Text)
        'calculamos la posición en y
        y = Me.ScaleHeight - ((FormPad * 2) + (i * lYDivition))
        'Trazamos la línea
        Me.Line (0, y)-(Me.ScaleWidth, y)
        With Label1(iCtrl)
            .Visible = False
            .Top = y + 1
            If m_lXOrigin < 0 Then
                .Left = 1
            ElseIf m_lXOrigin > (Me.ScaleWidth - (.Width + 1)) Then
                .Left = Me.ScaleWidth - (.Width + 1)
            Else
                .Left = m_lXOrigin + 1
            End If
            .Caption = Format(CLng(Text1(1).Text) + (i * Text1(3)), "###,##0.000")
            .Visible = True
        End With
        iCtrl = iCtrl + 1
    Next i
    
    'trazamos los ejes
    Me.DrawStyle = vbSolid
    Me.ForeColor = vbHighlight
    If (m_lYOrigin >= 0) And (m_lYOrigin <= Me.ScaleHeight) Then
        Me.Line (0, m_lYOrigin)-(Me.ScaleWidth, m_lYOrigin)
    End If
    
    If (m_lXOrigin >= 0) And (m_lXOrigin <= Me.ScaleWidth) Then
        Me.Line (m_lXOrigin, 0)-(m_lXOrigin, Me.ScaleHeight)
    End If
    
    Me.AutoRedraw = False
End Sub

'Esta función devuelve un código de error. El resultado de la evaluación se guarda en
'una variable pasada pro referencia (al estilo de las funciones de la API). De este
'modo, es mucho más fácil decidir que hacer según el error que ocurra.
'Por ahora, sólo manejamos la posibilidad de división por cero, pero tratándose
'de ecuaciones mátemáticas, pueden ocurrir muchos más.
Private Function Solve( _
        ByVal sEquation As String, _
        ByVal lXVal As Double, _
        ByRef lResult As Long) As EnumErrorSolve
        
Dim SC           As New ScriptControl
'Dim sEquation    As String
Dim dResult      As Double

On Error GoTo ErrorTrap

    'Establecemos el lenguaje con el que operara el SC
    'Si indicásemos que será JScript, las ecuaciones tendrían
    'que introducirse con la sintaxis de JScript.
    'Por ejemplo:
    'VBScript ->    ((2 * X) ^ 2) / (X - 1)
    'JScript  ->    Math.Pow(2 * X), 2) / (X - 1)
    SC.Language = "VBScript"
    'Exp
    'Remplazamos la "X" en la ecuación por el valor numérico
    'Hacemos la comparación en modo textual, así reemplazamos ya sea
    'una X mayúscula o minúscula.
    'Sim embargo esto ocasiona que expresiones como Exp() no
    'puedan ser evaluadas. Tendrás que corregir eso.
    sEquation = Replace(sEquation, "X", CStr(lXVal), , , vbTextCompare)
    
    'evaluamos
    dResult = SC.Eval(sEquation)
    
    'Convertimos el resultado a coordenadas de pantalla,
    'y devolvemos el valor.
    lResult = m_lYOrigin - CLng(dResult / m_lYValReal)
    
    Exit Function
    
ErrorTrap:

    Select Case Err.Number
        Case 5  'Argumento Inválido. Por ejemplo: Sqr(-1)
            lResult = ErrorSolve
            Solve = ESArgInvalid
            Err.Clear
        Case 6  'overflow
            lResult = ErrorSolve
            Solve = ESOverFlow
            Err.Clear
        Case 11 'División por cero
            'Es muy probable que al evaluar alguna ecuación se produzca
            'una división por cero. Aquí interceptamos el error.
            'Esto parece funcionar sólo en el archivo compilado...
            lResult = ErrorSolve
            Solve = ESInfinit
            Err.Clear
    End Select
End Function

Private Sub Form_Resize()
    'Esta verificación la hacemos para evitar que salte un error.
    'Ya que el formulario se redimensiona antes de que los controles a
    'usar hayan sido creados.
    If m_bAllowChange Then
        DrawGrid
    End If
End Sub

Private Sub Text1_Change(Index As Integer)
    If m_bAllowChange Then
        If IsNumeric(Text1(Index).Text) Then
            If Index > 1 Then
                If CSng(Text1(Index).Text) <> 0 Then
                    LoadUnloadLabels
                    DrawGrid
                End If
            Else
                LoadUnloadLabels
                DrawGrid
            End If
        End If
    End If
End Sub

Private Sub Timer1_Timer()
'¿Para qué es este timer? Visual Basic no permitirá que
'descargue dinámicamente los controles que utilizamos
'si la rutina que los descarga es invocada desde ciertos
'eventos. Puesto que para mostrar las funciones de ejemplo
'necesito redimensionar el array de Labels cuando el usuario
'hace click en el combo1, VB fallará catastróficamente.
'Entonces, en lugar de hacerlo con el evento del combo,
'lo hacemos con el timer unos milisegundos después
'del onclick del combo...
    
    Timer1.Enabled = False
    LoadUnloadLabels
    DrawGrid
End Sub
En lo personal, prefiero usar las funciones GDI de la API, porque son definitivamente más rápidas. En cuanto al control, es desesperantemente lento (comparado con el archivo que antes te había pasado), pero hace el trabajo, y es fácil de usar y comprender.
En el programa incluyo algunas ecuaciones que te pueden servir de ejemplo para que veas como introducir tus propias funciones. Ah, y seguramente te llegarán a saltar errores, al evaluar una función puede ocurrir un overflow, o que metan mal la función. Sólo he puesto intercepción de errores para división por cero y operador incorrecto...
Bueno, luego me dices como te fue con esto. Saludos.
P.D. Te dejo un screenshot del programa después de graficar las ecuaciones de una circunferencia y de una elipse...
screenshot
  #8 (permalink)  
Antiguo 18/02/2005, 14:06
 
Fecha de Ingreso: febrero-2005
Mensajes: 12
Antigüedad: 19 años, 2 meses
Puntos: 0
oye beakdan necesito tu ayuda

la verdad el programa es bien interesante, pero la verdad no entendí nada,
quise acoplar el cod a mi proyecto y la verdad no pude.. y creeme soy muy bueno en eso....

lo que yo necesito es basicamente esto:....
mi programa genera un tabla de dos columnas (X & Y)
lo que necesito es poder graficarlas ....
no necesito graficar funciones porque de lo contrario me serviria el programa que le mandaste a alexandra....
lo que necesito es graficas los puntos ejemplo
la tabla cargada en el msflexgrid es
(x,y)
(6,0.1)
(9,0.2)
(12,0.3)
etc, etc ,etc

si me puedes ayudar te lo agradeceria mucho
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 18:11.