?? curve.cpp
字號:
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : curve.cpp //
// Description: Path, curve transformation, styled curve //
// Version : 1.00.000, May 31, 2000 //
//-----------------------------------------------------------------------------------//
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <math.h>
#include <assert.h>
#include <tchar.h>
#include "curve.h"
#include "pen.h"
int KPathData::GetPathData(HDC hDC)
{
if ( m_pPoint ) delete m_pPoint;
if ( m_pFlag ) delete m_pFlag;
m_nCount = ::GetPath(hDC, NULL, NULL, 0);
if ( m_nCount>0 )
{
m_pPoint = new POINT[m_nCount];
m_pFlag = new BYTE[m_nCount];
if ( m_pPoint!=NULL && m_pFlag!=NULL )
m_nCount = ::GetPath(hDC, m_pPoint, m_pFlag, m_nCount);
}
return m_nCount;
}
void KPathData::MapPoints(K2DMap & map)
{
for (int i=0; i<m_nCount; i++)
map.Map(m_pPoint[i].x, m_pPoint[i].y);
}
BOOL KTransCurve::MoveTo(HDC hDC, int x, int y)
{
m_orgx = x;
m_orgy = y;
x0 = (float) x;
y0 = (float) y;
Map(x0, y0, m_dstx, m_dsty);
return DrvMoveTo(hDC, (int) (m_dstx+0.5), (int) (m_dsty+0.5));
}
BOOL KTransCurve::BezierTo(HDC hDC, float x1, float y1, float x2, float y2, float x3, float y3)
{
float dx3, dy3;
Map(x3, y3, dx3, dy3);
if ( ( fabs(dx3-m_dstx) + fabs(dy3-m_dsty) ) < m_seglen ) // no need to break ?
{
float dx1, dy1, dx2, dy2;
Map(x1, y1, dx1, dy1);
Map(x2, y3, dx2, dy2);
POINT P[3] = { (int) (dx1+0.5), (int) (dy1+0.5),
(int) (dx2+0.5), (int) (dy2+0.5),
(int) (dx3+0.5), (int) (dy3+0.5) };
x0 = x3;
y0 = y3;
m_dstx = dx3;
m_dsty = dy3;
return DrvBezierTo(hDC, P);
}
else
{
BezierTo(hDC,
(x0+x1) /2, (y0+y1) /2,
(x0+x1*2+x2) /4, (y0+y1*2+y2) /4,
(x0+x1*3+x2*3+x3)/8, (y0+y1*3+y2*3+y3)/8);
return BezierTo(hDC,
(x1+x2*2+x3)/4, (y1+y2*2+y3)/4,
(x2+x3) /2, (y2+y3) /2,
x3, y3);
}
}
BOOL KPathData::Draw(HDC hDC, KTransCurve & trans, bool bPath)
{
if ( m_nCount==0 )
return FALSE;
if ( bPath )
BeginPath(hDC);
for (int i=0; i<m_nCount; i++)
{
switch ( m_pFlag[i] & ~ PT_CLOSEFIGURE )
{
case PT_MOVETO:
trans.MoveTo(hDC, m_pPoint[i].x, m_pPoint[i].y);
break;
case PT_LINETO:
trans.LineTo(hDC, m_pPoint[i].x, m_pPoint[i].y);
break;
case PT_BEZIERTO:
trans.BezierTo(hDC,
m_pPoint[i ].x, m_pPoint[i ].y,
m_pPoint[i+1].x, m_pPoint[i+1].y,
m_pPoint[i+2].x, m_pPoint[i+2].y);
i+=2;
break;
default:
assert(false);
}
if ( m_pFlag[i] & PT_CLOSEFIGURE )
trans.CloseFigure(hDC);
}
if ( bPath )
EndPath(hDC);
return TRUE;
}
BOOL KStyleCurve::LineTo(double x, double y)
{
double x2 = x;
double y2 = y;
double curlen = sqrt((x2-m_x1)*(x2-m_x1) +
(y2-m_y1)*(y2-m_y1));
double length = m_pDash->GetLength(m_step);
while ( curlen >= length )
{
double x1 = m_x1;
double y1 = m_y1;
m_x1 += (x2-m_x1) * length / curlen;
m_y1 += (y2-m_y1) * length / curlen;
if ( ! m_pDash->DrawDash(x1, y1, m_x1, m_y1, m_step) )
return FALSE;
curlen -= length;
m_step ++;
length = m_pDash->GetLength(m_step);
}
return TRUE;
}
BOOL KStyleCurve::PolyDraw(const POINT *ppt, const BYTE *pbTypes, int nCount)
{
int lastmovex = 0;
int lastmovey = 0;
for (int i=0; i<nCount; i++)
{
switch ( pbTypes[i] & ~ PT_CLOSEFIGURE )
{
case PT_MOVETO:
m_x1 = lastmovex = ppt[i].x;
m_y1 = lastmovey = ppt[i].y;
break;
case PT_LINETO:
if ( ! LineTo(ppt[i].x, ppt[i].y) )
return FALSE;
break;
}
if ( pbTypes[i] & PT_CLOSEFIGURE )
if ( ! LineTo(lastmovex, lastmovey) )
return FALSE;
}
return TRUE;
}
void KPathData::MarkPoints(HDC hDC, bool bShowLine)
{
if ( bShowLine )
{
KPen dot(PS_DOT, 0, RGB(0xFF, 0, 0), hDC);
Polyline(hDC, m_pPoint, m_nCount);
}
KPen solid(PS_SOLID, 0, RGB(0, 0, 0xFF));
solid.Select(hDC);
HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0xFF));
for (int i=0; i<m_nCount; i++)
{
#ifdef _DEBUG
TCHAR temp[32];
wsprintf(temp, _T("%3d %d (%d,%d)\n"), i, m_pFlag[i], m_pPoint[i].x, m_pPoint[i].y);
OutputDebugString(temp);
#endif
int x = m_pPoint[i].x;
int y = m_pPoint[i].y;
if ( m_pFlag[i] & PT_CLOSEFIGURE )
SelectObject(hDC, hBrush);
else
SelectObject(hDC, GetStockObject(WHITE_BRUSH));
switch ( m_pFlag[i] & ~ PT_CLOSEFIGURE )
{
case PT_MOVETO:
{
POINT P[] = { x, y-6, x+6, y+4, x-6, y+4, x, y-6 };
Polygon(hDC, P, 4);
}
break;
case PT_LINETO:
Rectangle(hDC, x-5, y-5, x+5, y+5);
break;
case PT_BEZIERTO:
Ellipse(hDC, x-5, y-5, x+5, y+5);
break;
}
}
SelectObject(hDC, GetStockObject(WHITE_BRUSH));
DeleteObject(hBrush);
solid.UnSelect();
}
BOOL KDashes::DrawDash(double x1, double y1, double x2, double y2, int step)
{
HBRUSH hBrush = CreateSolidBrush(PALETTEINDEX(step % 20));
HGDIOBJ hOld = SelectObject(m_hDC, hBrush);
SelectObject(m_hDC, GetStockObject(NULL_PEN));
double dy = (x2-x1)/2;
double dx = (y2-y1)/2;
switch ( m_test & 3 )
{
case 0: // diamound
{
POINT P[5] = { (int)x1, (int)y1, (int)((x1+x2)/2-dx), (int)((y1+y2)/2+dy),
(int)x2, (int)y2, (int)((x1+x2)/2+dx), (int)((y1+y2)/2-dy),
(int)x1, (int)y1 };
Polygon(m_hDC, P, 5);
break;
}
case 1: // triangle
{
dx /= 0.866; // sqrt(3)/2
dy /= 0.866;
POINT P[4] = { (int)(x1-dx), (int)(y1+dy), (int)x2, (int)y2,
(int)(x1+dx), (int)(y1-dy), (int)(x1-dx), (int)(y1+dy)
};
Polygon(m_hDC, P, 4);
break;
}
case 2: // circle
{
double r = sqrt(dx * dx + dy * dy);
Ellipse(m_hDC, (int)((x1+x2)/2-r), (int)((y1+y2)/2-r),
(int)((x1+x2)/2+r), (int)((y1+y2)/2+r));
break;
}
case 3:
{
POINT P[5] = { (int)(x1-dx), (int)(y1+dy), (int)(x2-dx), (int)(y2+dy),
(int)(x2+dx), (int)(y2-dy), (int)(x1+dx), (int)(y1-dy),
(int)(x1-dx), (int)(y1+dy)
};
Polygon(m_hDC, P, 5);
break;
}
}
SelectObject(m_hDC, hOld);
DeleteObject(hBrush);
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -