// MFCSplineView.cpp : implementation of the CMFCSplineView class
//
/*##################################################################
Author: Masoud Samimi
Website: www.geocities.com/samimi73
Email: marcello43@hotmail.com
Program: MFC Spline Drawing Demo Application
History: Original code found from
http://www.planet-source-code.com as a GLUT based Spline Drawing Application
as their copyright appears below.
It was ported to MFC vesrsion by myself on 22.07.2000 (dd.mm.yy)
Purpose: Please visit my website, it is expalined there.
Important Notice:
This Idea and the Application is Copyright(c) Masoud Samimi 1999,2000.
You can freely use it as long as you credit me for it.
No guarantee/warantee is given on this app and I will not be responsible
for any damage to you, your property or any other person from using it.
USE IT ON YOUR OWN RISK.
Thankyou and have FUNNE =-)
Masoud Samimi.
Original source code:
//**************************************
// Name: OpenGL Spine drawing app
// Description:It's a Spline Drawing Application that uses the OpenGL Libraries. I used the GLUT event handler interface to control Mouse functions.You will Need:
// OpenGL
// Glut
// and a C++ compiler
// Found at: http://modzer0.cs.uaf.edu/~hartsock/C_Cpp/OpenGL/Splines.html
// By: Found on the World Wide Web
//
//
// Inputs:None
//
// Returns:None
//
//Assumes:None
//
//Side Effects:None
//
//Warranty:
//Code provided by Planet Source Code(tm) (http://www.Planet-Source-Code.com) 'as is', without warranties as to performance, fitness, merchantability,and any other warranty (whether expressed or implied).
//**************************************
/************************************************************************\
|
| Shawn R. Hartsock
| CS 381
| Prof: Hartman
| due: 11/4/1998
|
| Splines.c
| Draws Splines!
| Menus: Spline Type, Tension, Reset, Quit
| Keys : z,x,i,j,k,l,1,2,3
|Point: Drag to move spline points
|Rainbows free of charge.
| The color (rainbow) allows you to observe the "speed" at which
| the points are moving along the line toward the end point.
| Negative tension causes the control points to be weighted heavier...
| Positive tension up to 1.0 causes the control points to be weighted
| less, and a tension of 1.0 means that the control points are ignored.
| A tension of MORE than 1.0 means that the control points "push" the
| line rather than "pull" it, or vice versa (cardinal spline)... a
| Positive value greater than 1.0 makes the control points weighted
| NEGATIVELY.
\************************************************************************/
//##################################################################
#include "stdafx.h"
#include "math.h"
#include "MFCSpline.h"
#include "MFCSplineDoc.h"
#include "MFCSplineView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////
// Color Indexes
struct colorIndexState
{
GLfloat amb[3]; /* ambient color / bottom of ramp */
GLfloat diff[3]; /* diffuse color / middle of ramp */
GLfloat spec[3]; /* specular color / top of ramp */
GLfloat ratio; /* ratio of diffuse to specular in ramp */
GLint indexes[3]; /* where ramp was placed in palette */
};
#define NUM_COLORS (sizeof(colorv) / sizeof(colorv[0]))
struct colorIndexState colorv[] =
{
{
{ 0.0F, 0.0F, 0.0F },
{ 0.1F, 0.6F, 0.3F },
{ 1.0F, 1.0F, 1.0F },
0.75F, { 0, 0, 0 },
},
{
{ 0.0F, 0.0F, 0.0F },
{ 0.0F, 0.2F, 0.5F },
{ 1.0F, 1.0F, 1.0F },
0.75F, { 0, 0, 0 },
},
{
{ 0.0F, 0.05F, 0.05F },
{ 0.6F, 0.0F, 0.8F },
{ 1.0F, 1.0F, 1.0F },
0.75F, { 0, 0, 0 },
},
};
// Lighting components
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.6f, 0.6f, 0.6f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat m_lightPosX = -100.0f; // Light Position X axis
GLfloat m_lightPosY = -50.0f; // Light Position Y axis
GLfloat m_lightPosZ = 150.0f; // Light Position Z axis
GLfloat m_lightPosW = 1.0f; // Light Position W axis
GLfloat lightPos[4] = { m_lightPosX,m_lightPosY,m_lightPosZ,m_lightPosW };
//########################################################
// Spline Data
#ifndef M_PI
#define M_PI 3.14159265359
#endif
# define NUMSTEPS 0.01 /* <-- for win32 compatability */
#define DIST(a,b) sqrt( (a[0] - b[0] ) * ( a[0] - b[0] ) + (a[1] - b[1]) * (a[1] - b[1]) )
double P[4][2] = {
{0,0}, {50,250}, {300,300}, {350,350}
};
//
//########################################################
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView
IMPLEMENT_DYNCREATE(CMFCSplineView, CView)
BEGIN_MESSAGE_MAP(CMFCSplineView, CView)
//{{AFX_MSG_MAP(CMFCSplineView)
ON_WM_ERASEBKGND()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_CREATE()
ON_WM_QUERYNEWPALETTE()
ON_WM_PALETTECHANGED()
ON_COMMAND(ID_SPLINE_TENSION_1, OnSplineTension1)
ON_COMMAND(ID_SPLINE_TENSION_2, OnSplineTension2)
ON_COMMAND(ID_SPLINE_TENSION_3, OnSplineTension3)
ON_COMMAND(ID_SPLINE_TENSION_4, OnSplineTension4)
ON_COMMAND(ID_SPLINE_TENSION_5, OnSplineTension5)
ON_COMMAND(ID_SPLINE_TENSION_6, OnSplineTension6)
ON_COMMAND(ID_SPLINE_TENSION_7, OnSplineTension7)
ON_COMMAND(ID_SPLINE_TENSION_8, OnSplineTension8)
ON_COMMAND(ID_SPLINE_TENSION_9, OnSplineTension9)
ON_COMMAND(ID_SPLINE_TENSION_10, OnSplineTension10)
ON_COMMAND(ID_SPLINE_TENSION_11, OnSplineTension11)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_1, OnUpdateSplineTension1)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_2, OnUpdateSplineTension2)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_3, OnUpdateSplineTension3)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_4, OnUpdateSplineTension4)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_5, OnUpdateSplineTension5)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_6, OnUpdateSplineTension6)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_7, OnUpdateSplineTension7)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_8, OnUpdateSplineTension8)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_9, OnUpdateSplineTension9)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_10, OnUpdateSplineTension10)
ON_UPDATE_COMMAND_UI(ID_SPLINE_TENSION_11, OnUpdateSplineTension11)
ON_COMMAND(ID_SPLINE_RESET, OnSplineReset)
ON_COMMAND(ID_SLPINE_CARDINAL, OnSlpineCardinal)
ON_COMMAND(ID_SPLINE_BEZIER, OnSplineBezier)
ON_COMMAND(ID_SPLINE_HERMITE, OnSplineHermite)
ON_UPDATE_COMMAND_UI(ID_SLPINE_CARDINAL, OnUpdateSlpineCardinal)
ON_UPDATE_COMMAND_UI(ID_SPLINE_BEZIER, OnUpdateSplineBezier)
ON_UPDATE_COMMAND_UI(ID_SPLINE_HERMITE, OnUpdateSplineHermite)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_SPLINE_SELECT_ANCHORPOINT1, OnSplineSelectAnchorpoint1)
ON_COMMAND(ID_SPLINE_SELECT_ANCHORPOINT2, OnSplineSelectAnchorpoint2)
ON_COMMAND(ID_SPLINE_SELECT_TANGENTPOINT1, OnSplineSelectTangentpoint1)
ON_COMMAND(ID_SPLINE_SELECT_TANGENTPOINT2, OnSplineSelectTangentpoint2)
ON_UPDATE_COMMAND_UI(ID_SPLINE_SELECT_ANCHORPOINT1, OnUpdateSplineSelectAnchorpoint1)
ON_UPDATE_COMMAND_UI(ID_SPLINE_SELECT_ANCHORPOINT2, OnUpdateSplineSelectAnchorpoint2)
ON_UPDATE_COMMAND_UI(ID_SPLINE_SELECT_TANGENTPOINT1, OnUpdateSplineSelectTangentpoint1)
ON_UPDATE_COMMAND_UI(ID_SPLINE_SELECT_TANGENTPOINT2, OnUpdateSplineSelectTangentpoint2)
ON_WM_CONTEXTMENU()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView construction/destruction
CMFCSplineView::CMFCSplineView()
{
// TODO: add construction code here
m_ptLMouse = 0;
m_bLMouseDown = FALSE;
m_nSelectedPoint = 0;
m_dTension = 0.0;
m_dScale = 0.02;
T_Y = 5.0;
T_X = 5.0;
}
CMFCSplineView::~CMFCSplineView()
{
}
BOOL CMFCSplineView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_OWNDC);
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView drawing
void CMFCSplineView::OnDraw(CDC* pDC)
{
CMFCSplineDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// Make the rendering context current
wglMakeCurrent(m_hDC,m_hRC);
// Call to the rendering function
MainRenderScene();
// Swap our scene to the front
SwapBuffers(m_hDC);
// Allow other rendering contexts to co-exist
wglMakeCurrent(m_hDC,NULL);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView printing
BOOL CMFCSplineView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMFCSplineView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMFCSplineView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView diagnostics
#ifdef _DEBUG
void CMFCSplineView::AssertValid() const
{
CView::AssertValid();
}
void CMFCSplineView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMFCSplineDoc* CMFCSplineView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCSplineDoc)));
return (CMFCSplineDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMFCSplineView message handlers
BOOL CMFCSplineView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
}
void CMFCSplineView::OnMouseMove(UINT nFlags, CPoint point)
{
CPoint x = m_ptLMouse.x;
CPoint y = m_ptLMouse.y;
switch(nFlags){ //1
case MK_LBUTTON:
if (m_bLMouseDown){ //2
for(int ii=0; ii<4; ii++)
{ //3
if ( (( ( ((m_ptLMouse.x - point.x) / m_dScale) + T_Y)) > (P[ii][0]+10) )&&
(( ( ((m_ptLMouse.x - point.x) / m_dScale) + T_Y)) < (P[ii][0]-10) )&&
(( ( ((m_ptLMouse.y - point.y) / m_dScale) + T_X)) > (P[ii][1]+10) )&&
(( ( ((m_ptLMouse.y - point.y) / m_dScale) + T_X)) < (P[ii][1]-10) ))
{ //4
m_nMovePoint = ii;
Invalidate();
break;
} //4
else m_nMovePoint = 2;//1;//2;//3;//4;
Invalidate();
} //3
if(m_nMovePoint != 4)
{ //5
P[m_nMovePoint][0] = ((m_ptLMouse.x-point.x) / m_dScale) + T_X;
P[m_nMovePoint][1] = ((m_ptLMouse.y-point.y) / m_dScale) + T_Y;
break;
} //5
} //2
}//1
CView::OnMouseMove(nFlags, point);
}
void CMFCSplineView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
wglMakeCurrent(m_hDC,m_hRC);
GLsizei width, height;
GLdouble aspect;
width = cx;
height = cy;
if (cy==0)
aspect = (GLdouble)width;
else
aspect = (GLdouble)width/(GLdouble)height;
m_WHRatio = aspect; //save it for further use.
glViewport(0, 0, width, height);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Setup perspective for viewing
gluPerspective(35.0, m_WHRatio, 1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Viewing transformation, backup 100 units
glTranslatef(0.0f, 0.0f, -300.0f);
glScalef(15.0f, 15.0f, 15.0f);
wglMakeCurrent(NULL,NULL);
}
void CMFCSplineView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
// Clean up rendering context stuff
wglDeleteContext(m_hRC);
::ReleaseDC(m_hWnd,m_hDC);
}
int CMFCSplineView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
int nPixelFormat; // Pixel format index
m_hDC = ::GetDC(m_hWnd); // Get the Device context
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // Double buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
24, // Want 24bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
32, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
PFD_MAIN_PLANE, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(m_hDC, &pfd);
// Set the pixel format for the device context
VERIFY(SetPixelFormat(m_hDC, nPixelFormat, &pfd));
// Create the rendering context
m_hRC = wglCreateContext(m_hDC);
// Make the rendering context current, perform initialization, then
// deselect it
VERIFY(wglMakeCurrent(m_hDC,m_hRC));
wglMakeCurrent(NULL,NULL);
// Create the palette if needed
InitializePalette();
return 0;
}
// Initializes the CPalette object
void CMFCSplineView::InitializePalette(void)
{
PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE* pPal;
int pixelFormat = GetPixelFormat(m_hDC);
int paletteSize;
DescribePixelFormat(m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
/*
** Determine if a palette is needed and if so what size.
*/
if (pfd.dwFlags & PFD_NEED_PALETTE)
{
paletteSize = 1 << pfd.cColorBits;
}else
if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
{
paletteSize = 4096;
}else
{
return;
}
pPal = (LOGPALETTE*)
malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
pPal->palVersion = 0x300;
pPal->palNumEntries = paletteSize;
if (pfd.iPixelType == PFD_TYPE_RGBA)
{
/*
** Fill the logical paletee with RGB color ramps
*/
int redMask = (1 << pfd.cRedBits) - 1;
int greenMask = (1 << pfd.cGreenBits) - 1;
int blueMask = (1 << pfd.cBlueBits) - 1;
int i;
for (i=0; i<paletteSize; ++i)
{
pPal->palPalEntry[i].peRed =
(((i >> pfd.cRedShift) & redMask) * 255) / redMask;
pPal->palPalEntry[i].peGreen =
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
pPal->palPalEntry[i].peBlue =
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
pPal->palPalEntry[i].peFlags = 0;
}
}else
{
int numRamps = NUM_COLORS;
int rampSize = (paletteSize - 20) / numRamps;
int extra = (paletteSize - 20) - (numRamps * rampSize);
int i, r;
GetSystemPaletteEntries(m_hDC, 0, paletteSize, &pPal->palPalEntry[0]);
for (r=0; r<numRamps; ++r)
{
int rampBase = r * rampSize + 10;
PALETTEENTRY *pe = &pPal->palPalEntry[rampBase];
int diffSize = (int) (rampSize * colorv[r].ratio);
int specSize = rampSize - diffSize;
for (i=0; i<rampSize; ++i)
{
GLfloat *c0, *c1;
GLint a;
if (i < diffSize)
{
c0 = colorv[r].amb;
c1 = colorv[r].diff;
a = (i * 255) / (diffSize - 1);
}else
{
c0 = colorv[r].diff;
c1 = colorv[r].spec;
a = ((i - diffSize) * 255) / (specSize - 1);
}
pe[i].peRed = (BYTE) (a * (c1[0] - c0[0]) + 255 * c0[0]);
pe[i].peGreen = (BYTE) (a * (c1[1] - c0[1]) + 255 * c0[1]);
pe[i].peBlue = (BYTE) (a * (c1[2] - c0[2]) + 255 * c0[2]);
pe[i].peFlags = PC_NOCOLLAPSE;
}
colorv[r].indexes[0] = rampBase;
colorv[r].indexes[1] = rampBase + (diffSize-1);
colorv[r].indexes[2] = rampBase + (rampSize-1);
}
for (i=0; i<extra; ++i)
{
int index = numRamps*rampSize+10+i;
PALETTEENTRY *pe = &pPal->palPalEntry[index];
pe->peRed = (BYTE) 0;
pe->peGreen = (BYTE) 0;
pe->peBlue = (BYTE) 0;
pe->peFlags = PC_NOCOLLAPSE;
}
}
m_hPalette2 = CreatePalette(pPal);
free(pPal);
if(m_hPalette2)
{
SelectPalette(m_hDC, m_hPalette2, FALSE);
RealizePalette(m_hDC);
}
}
BOOL CMFCSplineView::EnableRC(HDC m_hDC, HGLRC m_hRC, BOOL bEnable)
{
if(bEnable)
{
if(!wglMakeCurrent(m_hDC, m_hRC))
{
if(m_bDisplayErrorMessages)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
MessageBox( /*NULL,*/ (LPTSTR)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
}
TRACE("3DeeZView::EnableRC - wglMakeCurrent failed\n");
return FALSE;
}
}
else
{
wglMakeCurrent(NULL, NULL);\
}
return TRUE;
}
BOOL CMFCSplineView::OnQueryNewPalette()
{
// If the palette was created.
if((HPALETTE)m_GLPalette)
{
int nRet;
// Selects the palette into the current device context
SelectPalette(m_hDC, (HPALETTE)m_GLPalette, FALSE);
// Map entries from the currently selected palette to
// the system palette. The return value is the number
// of palette entries modified.
nRet = RealizePalette(m_hDC);
// Repaint, forces remap of palette in current window
InvalidateRect(NULL,FALSE);
return nRet;
}
return CView::OnQueryNewPalette();
}
void CMFCSplineView::OnPaletteChanged(CWnd* pFocusWnd)
{
if(((HPALETTE)m_GLPalette != NULL) && (pFocusWnd != this))
{
// Select the palette into the device context
SelectPalette(m_hDC,(HPALETTE)m_GLPalette,FALSE);
// Map entries to system palette
RealizePalette(m_hDC);
// Remap the current colors to the newly realized palette
UpdateColors(m_hDC);
return;
}
CView::OnPaletteChanged(pFocusWnd);
}
void CMFCSplineView::MainRenderScene()
{
// Main Scene Color of the last selected parameters
glClearColor(0.0f,0.0f,0.0f,1.0f);
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Hidden surface removal
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// Light to setup propeties
glEnable(GL_LIGHTING);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
glMateriali(GL_FRONT,GL_SHININESS,100);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
/*
// Test for gl drawing only.
glPushMatrix();
glPointSize(5.0);
glBegin(GL_POLYGON);
glVertex2d(0.0,0.0);
glVertex2d(0.0,-5.0);
glVertex2d(-5.0,-5.0);
glVertex2d(-5.0,0.0);
glEnd();
glPopMatrix();
*/
//########################################################
// Spline drawing code
glPushMatrix();
glTranslated((-T_X),(-T_Y),0); /* move */
glScaled(m_dScale, m_dScale, 1);/* Zoom */
/* Draw Here */
if(m_nSelectedPoint == 0){
DrawArrows(P[0],P[1]); DrawArrows(P[2],P[3]);
}
DrawSpline();
DrawPoints();
glPopMatrix();
glFlush();
}
void CMFCSplineView::DrawPoints()
{
glPushMatrix();
glPointSize(6);
glBegin(GL_POINTS);
glColor3d(0.9, 0.1, 0.1);
for(int i=0; i<4; i++)
glVertex2i( (int) P[i][0], (int) P[i][1] );
glColor3d(1.0, 1.0, 1.0);
glEnd();
glPointSize(1.0);
glPopMatrix();
}
void CMFCSplineView::DrawArrows(double w1[2], double w2[2])
{
glPushMatrix();
glTranslated(w1[0],w1[1],0);
glRotated(atan2(w2[1]-w1[1],w2[0]-w1[0])*180/M_PI,0,0,1);
glScaled( DIST(w1,w2), DIST(w1,w2) ,1);
/* The portion of the code up to here may be useful in subsequent
programs. We have transformed coordinate space so that w1 has been
mapped to (0,0) and w2 has been mapped to (1,0). */
glBegin(GL_LINES);
glColor3d(0.9,0.9,0.2);
glVertex2d(0.0,0.0); glVertex2d(1.0,0.0);
glVertex2d(0.9,0.02); glVertex2d(1.0,0.0);
glVertex2d(0.9,-0.02); glVertex2d(1.0,0.0);
glColor3d(1.0,1.0,1.0);
glEnd();
glPopMatrix();
}
double CMFCSplineView::StartPoint(int i)
{
if(m_nSelectedPoint == 2) return P[1][i]; /*P2*/
else return P[0][i]; /*P1*/
}
double CMFCSplineView::EndPoint(int i)
{
if(m_nSelectedPoint == 1) return P[3][i]; /*P4*/
else return P[2][i]; /*P3*/
}
double CMFCSplineView::StartTangent(int i)
{
if(m_nSelectedPoint == 0){
return((1 - m_dTension)*(P[1][i] - P[0][i]) ); }
if(m_nSelectedPoint == 1){
return( 3 * (1 - m_dTension)*(P[1][i] - P[0][i]) ); }
if(m_nSelectedPoint == 2){
return((1 - m_dTension)*(P[2][i] - P[0][i]) /2 ); }
else return 0.0;
}
double CMFCSplineView::EndTangent(int i)
{
if(m_nSelectedPoint == 0){
return((1 - m_dTension)*(P[3][i] - P[2][i]) ); }
if(m_nSelectedPoint == 1){
return( 3 * (1-m_dTension)*(P[3][i] - P[2][i]) ); }
if(m_nSelectedPoint == 2){
return((1 - m_dTension)*(P[3][i] - P[1][i])/2 ); }
else return 0.0;
}
void CMFCSplineView::MakeSpline()
{
double R,G,B,t, vv[2];
double inc;
inc = NUMSTEPS;
R = 1.0; G = 0.7; B = 0.0;
for(t=0; t<=1; t+=inc){
for(int i=0; i<2; i++){
vv[i] = ((2*t*t*t)-(3*t*t)+1)*StartPoint(i)
+ ((-2*t*t*t)+(3*t*t))*EndPoint(i)
+ ((t*t*t)-(2*t*t)+t)*StartTangent(i)
+ ((t*t*t)-(t*t))*EndTangent(i);
}
R -= t * 0.08;
B += t * 0.08;
glColor3d(R,G,B);
glVertex2dv(vv);
}
}
void CMFCSplineView::DrawSpline()
{
glBegin(GL_LINE_STRIP);
MakeSpline();
glEnd();
}
void CMFCSplineView::OnSplineTension1()
{
// TODO: Add your command handler code here
m_dTension = -2.0;
Invalidate();
}
void CMFCSplineView::OnSplineTension2()
{
// TODO: Add your command handler code here
m_dTension = -1.0;
Invalidate();
}
void CMFCSplineView::OnSplineTension3()
{
// TODO: Add your command handler code here
m_dTension = -0.5;
Invalidate();
}
void CMFCSplineView::OnSplineTension4()
{
// TODO: Add your command handler code here
m_dTension = 0.0;
Invalidate();
}
void CMFCSplineView::OnSplineTension5()
{
// TODO: Add your command handler code here
m_dTension = 0.2;
Invalidate();
}
void CMFCSplineView::OnSplineTension6()
{
// TODO: Add your command handler code here
m_dTension = 0.4;
Invalidate();
}
void CMFCSplineView::OnSplineTension7()
{
// TODO: Add your command handler code here
m_dTension = 0.6;
Invalidate();
}
void CMFCSplineView::OnSplineTension8()
{
// TODO: Add your command handler code here
m_dTension = 0.8;
Invalidate();
}
void CMFCSplineView::OnSplineTension9()
{
// TODO: Add your command handler code here
m_dTension = 1.0;
Invalidate();
}
void CMFCSplineView::OnSplineTension10()
{
// TODO: Add your command handler code here
m_dTension = 2.0;
Invalidate();
}
void CMFCSplineView::OnSplineTension11()
{
// TODO: Add your command handler code here
m_dTension = 4.0;
Invalidate();
}
void CMFCSplineView::OnUpdateSplineTension1(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==-2.0);
}
void CMFCSplineView::OnUpdateSplineTension2(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==-1.0);
}
void CMFCSplineView::OnUpdateSplineTension3(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==-0.5);
}
void CMFCSplineView::OnUpdateSplineTension4(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==0.0);
}
void CMFCSplineView::OnUpdateSplineTension5(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==0.2);
}
void CMFCSplineView::OnUpdateSplineTension6(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==0.4);
}
void CMFCSplineView::OnUpdateSplineTension7(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==0.6);
}
void CMFCSplineView::OnUpdateSplineTension8(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==0.8);
}
void CMFCSplineView::OnUpdateSplineTension9(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==1.0);
}
void CMFCSplineView::OnUpdateSplineTension10(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==2.0);
}
void CMFCSplineView::OnUpdateSplineTension11(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(m_dTension==4.0);
}
void CMFCSplineView::OnSplineReset()
{
// TODO: Add your command handler code here
P[0][0] = 0;
P[0][1] = 0;
P[1][0] = 1;
P[1][1] = 20;
P[2][0] = 15;
P[2][1] = 15;
P[3][0] = 5;
P[3][1] = 20;
T_Y = 5.0000;
T_X = 5.0000;
m_dScale = 0.5;
m_dTension = 0.0;
m_nSelectedPoint = 0;
Invalidate();
}
void CMFCSplineView::OnSlpineCardinal()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 0;
Invalidate();
}
void CMFCSplineView::OnSplineBezier()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 1;
Invalidate();
}
void CMFCSplineView::OnSplineHermite()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 2;
Invalidate();
}
void CMFCSplineView::OnUpdateSlpineCardinal(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 0);
}
void CMFCSplineView::OnUpdateSplineBezier(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 1);
}
void CMFCSplineView::OnUpdateSplineHermite(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 2);
}
void CMFCSplineView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptLMouse = point;
m_bLMouseDown = TRUE;
SetCapture();
Invalidate();
HCURSOR hCursor = NULL;
CWinApp *cWinApp = AfxGetApp ();
hCursor = cWinApp->LoadCursor(IDC_CURSOR_CROSS);
SetCursor(hCursor);
CView::OnLButtonDown(nFlags, point);
}
void CMFCSplineView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptLMouse = 0;
m_bLMouseDown = FALSE;
ReleaseCapture();
Invalidate();
HCURSOR hCursor = NULL;
CWinApp *cWinApp = AfxGetApp ();
hCursor = LoadCursor (NULL, IDC_ARROW);
SetCursor(hCursor);
CView::OnLButtonUp(nFlags, point);
}
void CMFCSplineView::OnSplineSelectAnchorpoint1()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 1;
Invalidate();
}
void CMFCSplineView::OnSplineSelectAnchorpoint2()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 2;
Invalidate();
}
void CMFCSplineView::OnSplineSelectTangentpoint1()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 3;
Invalidate();
}
void CMFCSplineView::OnSplineSelectTangentpoint2()
{
// TODO: Add your command handler code here
m_nSelectedPoint = 4;
Invalidate();
}
void CMFCSplineView::OnUpdateSplineSelectAnchorpoint1(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 1);
}
void CMFCSplineView::OnUpdateSplineSelectAnchorpoint2(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 2);
}
void CMFCSplineView::OnUpdateSplineSelectTangentpoint1(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 3);
}
void CMFCSplineView::OnUpdateSplineSelectTangentpoint2(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_nSelectedPoint == 4);
}
void CMFCSplineView::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
// make sure window is active
GetParentFrame()->ActivateFrame();
CPoint local = point;
ScreenToClient(&local);
CMenu menu;
if (menu.LoadMenu(ID_POPUP_MENU))
{
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup != NULL);
pPopup->TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN,
point.x, point.y,
AfxGetMainWnd()); // route commands through main window
}
}