//---------------------------------------------------------------------------- // 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; }