//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dc.h>
#include <owl\inputdia.h>
#include <owl\opensave.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <classlib\arrays.h>
#include "spline.rc"
struct puntos
{
float x; // coorde valor(x)
float y; // nadas valor(y)
float t; // Angulo de abertura
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);
int QueryPen() const { return PenSize; }
int QueryPen(int penSize);
void traza(void);
float hermite(int, int, int, int, float);
int distancia(struct puntos*,float,float);
void marca(int,int);
protected:
int PenSize;
TOpenSaveDialog::TData
*FileData;
BOOL IsDirty, IsNewFile;
int GetPenSize();
// Override member function of TWindow
BOOL CanClose();
// Message response functions
void EvLButtonDown(UINT, TPoint&);
void EvRButtonDown(UINT, TPoint&);
void CmSalir();
void CmPenSize();
void CmAbout();
DECLARE_RESPONSE_TABLE(TMyWindow);
};
int TMyWindow::QueryPen(int penSize)
{
if (penSize < 0)
PenSize = 1;
else if (penSize > 0)
PenSize = penSize;
return PenSize;
}
DEFINE_RESPONSE_TABLE1(TMyWindow, TWindow)
EV_WM_LBUTTONDOWN,
EV_WM_RBUTTONDOWN,
EV_WM_MOUSEMOVE,
EV_WM_LBUTTONUP,
EV_COMMAND(CM_FILEEND, CmSalir),
EV_COMMAND(CM_ABOUT, CmAbout),
EV_COMMAND(CM_PENSIZE, CmPenSize),
END_RESPONSE_TABLE;
TMyWindow::TMyWindow(TWindow *parent)
{
Init(parent, 0, 0);
IsNewFile = TRUE;
IsDirty = FALSE;
FileData = new TOpenSaveDialog::TData(OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,
"Point Files (*.PT8)|*.pt8|", 0, "",
"PT8");
}
BOOL TMyWindow::CanClose()
{ return TRUE; }
void TMyWindow::EvLButtonDown(UINT, TPoint& point)
{
struct puntos *nodo = NULL;
struct puntos *act = NULL;
struct puntos *ant = NULL;
char s[16];
TClientDC dc(*this);
n_puntos++;
wsprintf(s, "%d",n_puntos);
dc.TextOut(point, s, strlen(s));
marca(point.x, point.y);
nodo = (struct puntos *)malloc(sizeof(struct puntos));
nodo->x = point.x;
nodo->y = point.y;
nodo->t = 0; // nodo->t = GetPenSize();
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
limpiar = 0;
inicio = NULL;
n_puntos = 0;
}
else
{
traza();
limpiar = 1;
}
}
void TMyWindow::CmSalir()
{ exit(1); }
void TMyWindow::CmPenSize()
{ ; }
int TMyWindow::GetPenSize()
{
char inputText[6];
int angulo = 1;
"Introduzca la pendiente:",
inputText,
sizeof(inputText))).Execute() == IDOK) {
angulo = atoi(inputText);
if (angulo < 0)
angulo = 360 + angulo;
}
return angulo;
}
void TMyWindow::CmAbout()
{ TDialog(this, IDD_ABOUT).Execute(); }
class TMyApp : public TApplication {
public:
TMyApp() : TApplication() {}
void InitMainWindow()
{
GetMainWindow()->AssignMenu("COMMANDS");
}
};
void TMyWindow::traza(void)
{
struct puntos *act = inicio;
struct puntos *pk0 = NULL;
struct puntos *pk1 = NULL;
struct puntos *pk2 = NULL;
struct puntos *pk3 = NULL;
char error[40];
float u, x, y;
TClientDC dc(*this);
if(n_puntos > 3) // existen al menos 4 puntos
{
while(act) // mientras haya puntos
{
pk0 = act;
if(pk0->sig) pk1 = pk0->sig; else break;
if(pk1->sig) pk2 = pk1->sig; else break;
if(pk2->sig) pk3 = pk2->sig; else break;
for(u=0; u<=1; u += 0.001)
{
x = hermite(pk0->x, pk1->x, pk2->x, pk3->x, u);
y = hermite(pk0->y, pk1->y, pk2->y, pk3->y, u);
SetPixel(dc, x, y, 8); // pone un punto en la ventana
}
act = act->sig;
}
}
else
{
wsprintf(error, "- %s -","No hay puntos suficientes");
dc.TextOut(10,10, error, strlen(error));
}
}
float TMyWindow::hermite(int pk0, int pk1, int pk2, int pk3, float u)
{
float u2, u3, s = 0.5, valor;
u2 = u*u;
u3 = u*u*u;
valor = pk0 * (-s*u3 + 2*s*u2 - s*u) +
pk1 * ( (2-s)*u3 + (s-3)*u2 + 1) +
pk2 *( (s-2)*u3 +(3-2*s)*u2 + s*u) +
pk3 * (s*u3 - s*u2);
return valor;
}
void TMyWindow::marca(int x, int y)
{
TClientDC dc(*this);
int x1, y1;
for(x1=x-5;x1<=x+5;x1++) SetPixel(dc, x1, y, 8);
for(y1=y-5;y1<=y+5;y1++) SetPixel(dc, x, y1, 8);
}
int OwlMain(int /*argc*/, char* /*argv*/ [])
{
inicio = NULL;
TMyApp().Run();
return 1;
}