Problema al graficar una función lineal (winbgim)

Iniciado por carlmycol, 9 Febrero 2013, 23:10 PM

0 Miembros y 1 Visitante están viendo este tema.

carlmycol

Bueno pues, inventando, como siempre, se me ocurrio hacer un programa que grafique una funcion lineal, peero, me llegó un problema extraño, no le veo la lógica, aún.

#include <stdio.h>
#include <stdlib.h>
#include <winbgim.h>
#include <math.h>

#define WIDTH 960
#define HEIGHT 600
#define PI 3.1415

int main()
{
    long long x, y, z;
    initwindow(WIDTH, HEIGHT);

    setcolor(COLOR(157, 157, 157));

    line(WIDTH/2, 0, WIDTH/2, HEIGHT);
    line(0, HEIGHT/2, WIDTH, HEIGHT/2);

    for (int i=0; i<=WIDTH; i++)
    {
        x = (i - WIDTH/2);
        if (x!=0) y=x-2;
        if (y<=0)
        {
            z=HEIGHT/2 + abs(y);
        } if (y>0)
        {
            z = abs(HEIGHT/2 - y);
        }
        if (z<=HEIGHT && z>=0) putpixel(i, z, COLOR(255, 255, 255));
        printf("f(%d) = %d\n", i, z); //el printf es para ver que pasa con esos valores o.0

    }


    getch();
    closegraph();
    return 0;
}


El problema es el siguiente:


WTF? Por qué pasa eso? 0.0
Casi parece una funcion de valor absoluto, pero no, en este caso es y=x-2, probé con y=2; y=40, es decir "y" constante y grafica perfectamente. ¿Por qué será? o.0

Hahahaha, si saben algo gracias, se me despejaría una gran duda


Saludos

do-while

¡Buenas!

No dibuja bien la grafica porque le estas dando mal las coordenadas.

Solo deberias de dibujar los puntos que cunplan que tanto i como HEIGHT/2 - y (o lo que es lo mismo HEIGHT/2 - i + WIDTH/2 + 2) esten dentro del area que has establecido para la grafica...

Si pones
            z = abs(HEIGHT/2 - y);

e y es mayor que HEIGHT / 2 y la funcion es continua, la grafica evidentemente "rebotara" en la parte superior debido al valor absoluto...

decir que cuando y sea negativo z = HEIGHT/2 + abs(y); es lo mismo que hacer z = HEIGHT/2 - y, por lo tanto distinguir entre valores positivos y negativos te da lo mismo, ya que la formula para calcular la fila donde tienes que dibujar el punto va a ser la misma independientemente de si y es mayor o menor que cero.

Con estas correcciones, como ya te he dicho, solo tienes que asegurarte de que los valores de i y z entren dentro del area de la grafica...

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

carlmycol

Hola! Muchas gracias por responder!

La verdad un no entiendo lo que me propones. Y aún no entiendo por qué sucede.

Con la función seno grafico sin problema alguno
Código (cpp) [Seleccionar]
...
...
#define WIDTH 720
#define HEIGHT 600
#define PI 3.1415

int main()
{
   float x, y;
   int z;
   initwindow(WIDTH, HEIGHT);

   setcolor(COLOR(157, 157, 157));

   line(WIDTH/2, 0, WIDTH/2, HEIGHT);
   line(0, HEIGHT/2, WIDTH, HEIGHT/2);

   for (int i=0; i<=WIDTH; i++)
   {
       x = (i - (WIDTH/2));
       y=sin((2*PI*x)/640)*50;
       printf("f(%f) = %f\n", x, y);
       if (y<=0)
       {
           z=HEIGHT/2 - y;
       } if (y>=0)
       {
           z = abs(HEIGHT/2 - y);
       }
       if (z<HEIGHT && z>0 && i<WIDTH && i>0)
       {
           putpixel(i, z, COLOR(255, 255, 255));
       }
   }
   getch();
   closegraph();
   return 0;
}


Al igual que con la funcion f(x)=b
Código (cpp) [Seleccionar]
...
...
#define WIDTH 720
#define HEIGHT 600
#define PI 3.1415

int main()
{
   float x, y;
   int z;
   initwindow(WIDTH, HEIGHT);

   setcolor(COLOR(157, 157, 157));

   line(WIDTH/2, 0, WIDTH/2, HEIGHT);
   line(0, HEIGHT/2, WIDTH, HEIGHT/2);

   for (int i=0; i<=WIDTH; i++)
   {
       x = (i - (WIDTH/2));
       //y=sin((2*PI*x)/640)*50;
       y=-20;
       printf("f(%f) = %f\n", x, y);
       if (y<=0)
       {
           z=HEIGHT/2 - y;
       } if (y>=0)
       {
           z = abs(HEIGHT/2 - y);
       }
       if (z<HEIGHT && z>0 && i<WIDTH && i>0)
       {
           putpixel(i, z, COLOR(255, 255, 255));
       }
   }
   getch();
   closegraph();
   return 0;
}




Ví que se grafica perfectamente con una ventana de height=width... Pero...
¿Por qué sucede ese "rebote" del f(x)=x-2 que mostré al principio? O.o

Saludos

do-while

#3
¡Buenas!

Ya te he dicho que es lo que pasa. Te lo puedo explicar de otra forma.

Si quieres encajar el punto (x,f(x)) en el rectangulo que tienes solo tienes que dibujar el punto (x + WIDTH / 2 , f(x) - HEIGHT / 2), siempre y cuando este dentro del rectangulo.

Por cierto, deberias de dibujar tambien el segmento que une dos puntos consecutivos, ya que de lo contrario, si |f(i+1) - f(i)| > 1, en lugar de una linea obtendras dos puntos separados. Solo tienes que probar con la funcion y = k*x con |k| > 1 o con los puntos de la forma (r * cos(t), r * sen(t)) donde 0 < r < min(WIDTH / 2 , HEIGHT / 2) y los t forman una particion del intervalo [0,2*Pi], y veras que solo obtienes un monton de puntos, no una curva continua que los una.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!