BEZIER.cpp



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