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