//----------------------------------------------------------------------------
// Programa: Bezier
// Objetivo: Trazar las curvas de Bezier con n puntos de control
// Autor: J. Rafael Rodriguez Ochoa
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dc.h>
#include <string.h>
#include <stdio.h>
#define MAX_CONTROL 4 // Control del numero de puntos
struct puntos
{
int x;
int y;
struct puntos *sig;
};
struct puntos *inicio; // Apuntador al primer nodo
int n_puntos = 0; // Puntos seleccionados con el raton
int limpiar = 0; // Bandera para limpiar la ventana
class TMyWindow : public TWindow {
public:
TMyWindow(TWindow *parent = 0);
void traza(void);
protected:
// Override member function of TWindow
BOOL CanClose();
// Message response functions
void EvLButtonDown(UINT, TPoint&);
void EvRButtonDown(UINT, TPoint&);
DECLARE_RESPONSE_TABLE(TMyWindow);
};
DEFINE_RESPONSE_TABLE1(TMyWindow, TWindow)
EV_WM_LBUTTONDOWN,
EV_WM_RBUTTONDOWN,
END_RESPONSE_TABLE;
TMyWindow::TMyWindow(TWindow *parent)
{
Init(parent, 0, 0);
}
BOOL TMyWindow::CanClose()
{
return MessageBox("Quieres archivar?", "Contenido modificado",
MB_YESNO | MB_ICONQUESTION) == IDNO;
}
void TMyWindow::EvLButtonDown(UINT, TPoint& point)
{
struct puntos *nodo = NULL;
struct puntos *act = NULL;
struct puntos *ant = NULL;
char s[16];
TClientDC dc(*this);
if (n_puntos != MAX_CONTROL)
{
n_puntos++;
wsprintf(s, "%d",n_puntos);
dc.TextOut(point, s, strlen(s));
nodo = (struct puntos *)malloc(sizeof(struct puntos));
nodo->x = point.x;
nodo->y = point.y;
nodo->sig = NULL;
if(!inicio) inicio = nodo;
else
{
act = inicio;
while(act) { ant = act; act = act->sig; }
ant->sig = nodo;
}
}
}
void TMyWindow::EvRButtonDown(UINT, TPoint&)
{
if (limpiar)
{
Invalidate(); // limpia ventana
inicio = NULL;
n_puntos = 0;
limpiar = 0;
}
else
{
traza();
limpiar = 1;
}
}
class TMyApp : public TApplication {
public:
TMyApp() : TApplication() {}
void InitMainWindow()
{
SetMainWindow(new TFrameWindow(0, " - Curvas de Bezier -", new TMyWindow));
}
};
void TMyWindow::traza(void)
{
struct puntos *pc1 = NULL;
struct puntos *pc2 = NULL;
struct puntos *pc3 = NULL;
struct puntos *pc4 = NULL;
char s[20];
float u;
int x, y;
TClientDC dc(*this);
if(n_puntos == MAX_CONTROL) // existen siempre 4 puntos
{
pc1 = inicio;
pc2 = inicio->sig;
pc3 = inicio->sig->sig;
pc4 = inicio->sig->sig->sig;
for(u=0;u<=1;u += .001)
{
x = pc1->x*(1-u*u*u+3*u*u-3*u) +
pc2->x*(3*u*u*u-6*u*u+3*u) +
pc3->x*(3*u*u-3*u*u*u) +
pc4->x*(u*u*u);
y = pc1->y*(1-u*u*u+3*u*u-3*u) +
pc2->y*(3*u*u*u-6*u*u+3*u) +
pc3->y*(3*u*u-3*u*u*u) +
pc4->y*(u*u*u);
SetPixel(dc, x, y, 8); // pone un punto en la ventana
}
}
else
{
wsprintf(s, "- %s -","No hay puntos suficientes");
dc.TextOut(10,10, s, strlen(s));
}
}
int OwlMain(int /*argc*/, char* /*argv*/ [])
{
inicio = NULL;
TMyApp().Run();
return 1;
}