📄 createpenview.cpp
字号:
// CreatePenView.cpp : implementation of the CCreatePenView class
//
#include "stdafx.h"
#include "CreatePen.h"
#include "CreatePenDoc.h"
#include "CreatePenView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//直线的DDA算法生成
#define ROUND(a) ((int)(a + 0.5))
void LineDDA2(int xa, int ya, int xb, int yb, CDC* pDC)
{
int dx = xb - xa;
int dy = yb - ya;
int Steps, k;
float xIncrement, yIncrement;
float x = xa, y = ya ;
if(abs(dx) > abs(dy))
Steps = abs(dx);
else
Steps = abs(dy);
xIncrement = dx/(float)Steps;
yIncrement = dy/(float)Steps;
pDC->SetPixel(ROUND(x), ROUND(y), RGB(255, 0, 0));
for(k=0; k<Steps; k++){
x += xIncrement;
y += yIncrement;
Sleep(10);
pDC->SetPixel(ROUND(x), ROUND(y), RGB(255, 0, 0));
}
}
//直线的Bresenham生成算法
void LineBres(int xa, int ya, int xb, int yb, CDC* pDC)
{
int dx = abs(xa - xb), dy = abs(ya - yb);
int p = 2*dy - dx;
int twoDy = 2*dy, twoDyDx = 2*(dy - dx);
int x, y , xEnd;
if(xa > xb){
x = xb;
y = yb;
xEnd = xa;
}
else{
x = xa;
y = ya;
xEnd = xb;
}
pDC->SetPixel(x, y, RGB(255, 0, 0));
while(x < xEnd){
x++;
if(p < 0)
p += twoDy;
else{
y++;
p += twoDyDx;
}
Sleep(10);
pDC->SetPixel(x, y, RGB(255, 0, 0));
}
}
void CirclePlotPoint(int xCenter, int yCenter, int x, int y, CDC* pDC)
{
pDC->SetPixel(xCenter + x, yCenter + y, RGB(255, 0, 0));
pDC->SetPixel(xCenter - x, yCenter + y, RGB(255, 0, 0));
pDC->SetPixel(xCenter + x, yCenter - y, RGB(255, 0, 0));
pDC->SetPixel(xCenter - x, yCenter - y, RGB(255, 0, 0));
pDC->SetPixel(xCenter + y, yCenter + x, RGB(255, 0, 0));
pDC->SetPixel(xCenter - y, yCenter + x, RGB(255, 0, 0));
pDC->SetPixel(xCenter + y, yCenter - x, RGB(255, 0, 0));
pDC->SetPixel(xCenter - y, yCenter - x, RGB(255, 0, 0));
}
//Bresenham生成圆弧的算法
void Bre_Arc(int xCenter, int yCenter, int Radius, CDC* pDC)
{
int x, y, distance;
x = 0;
y = Radius;
distance = 3 - 2 * Radius;
while(x < y){
Sleep(10);
//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
pDC->SetPixel(x, y, RGB(255, 0, 0));
if(distance < 0)
distance += 4 * x + 6;
else{
distance += 4 * (x - y) + 10;
y = y - 1;
}
x = x + 1;
}
if( x = y)
//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
pDC->SetPixel(x, y, RGB(255, 0, 0));
}
//正负法绘圆弧
void pn_Arc(int xCenter, int yCenter, int radius, CDC* pDC)
{
int x, y, f;
x = xCenter;
y = yCenter + radius;
f = 0;
while(y > yCenter){
Sleep(10);
//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
pDC->SetPixel(x, y, RGB(255, 0, 0));
if(f > 0){
f = f - 2 * (y - yCenter) + 1;
y = y - 1;
}
else{
f = f + 2 * (x - xCenter) + 1;
x = x + 1;
}
}
if(y = yCenter)
//CirclePlotPoint(xCenter, yCenter, x, y, pDC);
pDC->SetPixel(x, y, RGB(255, 0, 0));
}
//中点圆算法
void CircleMidpoint(int xCenter, int yCenter, int radius, CDC* pDC)
{
int x = 0 ;
int y = radius;
int p = 1 - radius; //初始决策参数
CirclePlotPoint(xCenter, yCenter, x, y, pDC);
Sleep(10);
while(x < y){
x++;
if(p < 0)
p += 2 * x + 1;
else{
y--;
p += 2 * (x - y) + 1;
}
Sleep(20);
CirclePlotPoint(xCenter, yCenter, x, y, pDC);
}
}
void EllispePlotPoints(int xCenter, int yCenter, int x, int y, CDC* pDC)
{
pDC->SetPixel(xCenter + x, yCenter + y, RGB(255, 0, 0));
pDC->SetPixel(xCenter - x, yCenter + y, RGB(255, 0, 0));
pDC->SetPixel(xCenter + x, yCenter - y, RGB(255, 0, 0));
pDC->SetPixel(xCenter - x, yCenter - y, RGB(255, 0, 0));
}
//中点法绘制椭圆
void EllispeMidPoint(int xCenter, int yCenter, int Rx, int Ry, CDC* pDC)
{
int Rx2 = Rx * Ry;
int Ry2 = Ry * Ry;
int twoRx2 = 2 * Rx2;
int twoRy2 = 2 * Ry2;
int p;
int x = 0;
int y = Ry;
int px = 0;
int py = twoRy2 * y;
EllispePlotPoints(xCenter, yCenter, x, y, pDC);
p = ROUND(Ry2 - (Rx2 * Ry) + (0.25 * Rx2));
while(px < py){
x++;
px += twoRy2;
if(p < 0)
p += Ry2 + px;
else{
y--;
py -= twoRx2;
p += Ry2 + px - py;
}
EllispePlotPoints(xCenter, yCenter, x, y, pDC);
}
p = ROUND(Ry2 * (x + 0.5) * (x + 0.5) + Rx2 * (y - 1) * (y -1) - Rx2 * Ry2);
while(y > 0){
y--;
py -= twoRx2;
if(p > 0)
p += Rx2 - py;
else{
x++;
px += twoRy2;
p += Rx2 - py + px;
}
EllispePlotPoints(xCenter, yCenter, x, y, pDC);
}
}
////////////////////////////梁友栋-BARSKY算法/////////////////////////
int ClipTest(float q, float d, float* t1, float* t2)
{
float r;
int retVal = TRUE;
if(q < 0.0){
r = d / q;
if(r > *t2)
retVal = FALSE;
else if(r > *t1)
*t1 = r;
}
else{
if(q > 0.0){
r = d / q;
if(r < *t1)
retVal = FALSE;
else if(r < *t2)
*t2 = r;
}
else if(d < 0.0)
retVal = FALSE;
}
return (retVal);
}
void ClipLine(POINT winMin, POINT winMax, POINT p1, POINT p2, CDC* pDC)
{
float t1 = 0.0, t2 = 1.0;
float dx = p2.x - p1.x , dy;
if(ClipTest(-dx, p1.x - winMin.x, &t1, &t2))
if(ClipTest(dx, winMax.x - p1.x, &t1, &t2)){
dy = p2.y - p1.y;
if(ClipTest(-dy, p1.y - winMin.y, &t1, &t2))
if(ClipTest(dy, winMax.y - p1.y, &t1, &t2)){
if(t2 < 1.0){
p2.x = p1.x + t2 * dx;
p2.y = p1.y + t2 * dy;
}
if(t1 > 0.0){
p1.x += t1 * dx;
p1.y += t1 * dy;
}
//pDC->MoveTo(ROUND(p1.x),ROUND(p1.y));
//pDC->LineTo(ROUND(p2.x), ROUND(p2.y));
LineDDA2(ROUND(p1.x),ROUND(p1.y), ROUND(p2.x), ROUND(p2.y), pDC);
}
}
}
////////////////////////////梁友栋-BARSKY算法/////////////////////////
////////////////////////////边界填充算法//////////////////////////////
void BoundaryFill4(int x, int y, COLORREF fillClr, COLORREF edgeClr, CDC* pDC)
{
COLORREF currentPixel;
currentPixel = pDC->GetPixel(x, y);
if((currentPixel != edgeClr) && (currentPixel != fillClr)){
pDC->SetPixel(x, y,fillClr);
Sleep(1);
BoundaryFill4(x + 1, y, fillClr, edgeClr, pDC);
BoundaryFill4(x - 1, y, fillClr, edgeClr, pDC);
BoundaryFill4(x, y + 1, fillClr, edgeClr, pDC);
BoundaryFill4(x, y - 1, fillClr, edgeClr, pDC);
}
}
////////////////////////////边界填充算法//////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView
IMPLEMENT_DYNCREATE(CCreatePenView, CView)
BEGIN_MESSAGE_MAP(CCreatePenView, CView)
//{{AFX_MSG_MAP(CCreatePenView)
ON_COMMAND(ID_DDA_LINE, OnDdaLine)
ON_COMMAND(ID_MIDLLDEPOINT_CIRCLE, OnMidlldepointCircle)
ON_COMMAND(ID_BRESENHAM_LINE, OnBresenhamLine)
ON_COMMAND(ID_PN_ARC, OnPnArc)
ON_COMMAND(ID_BRESENHAM_ARC, OnBresenhamArc)
ON_COMMAND(ID_MIDPOINTELLIPSE, OnMidpointellipse)
ON_COMMAND(ID_LIANG_BARSKY, OnLiangBarsky)
ON_COMMAND(ID_BOUNDARY_FILL, OnBoundaryFill)
ON_COMMAND(ID_TRANSFORM, OnTransform)
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView construction/destruction
CCreatePenView::CCreatePenView()
{
// TODO: add construction code here
m_ptStart.x = 100;
m_ptStart.y = 50;
m_ptEnd.x = 500;
m_ptEnd.y = 400;
}
CCreatePenView::~CCreatePenView()
{
}
BOOL CCreatePenView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView drawing
void CCreatePenView::OnDraw(CDC* pDC)
{
CCreatePenDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//创建画笔方法1
/* for(int i=0 ;i<7 ;i++)
{
CPen NewPen1(PS_SOLID+i,1,RGB(255,0,0));//(COLORREF)0x000000FF
CPen *pOldPen=pDC->SelectObject(&NewPen1);
pDC->MoveTo(10,20*i+10);
pDC->LineTo(700,20*i+10);
pDC->SelectObject(pOldPen);
}*/
//创建画笔方法2;
/*
for(int j=0 ;j<7 ;j++)
{
CPen NewPen2;
NewPen2.CreatePen(PS_SOLID,j,(COLORREF)0x00FF0000);//
CPen *pOldPen1=pDC->SelectObject(&NewPen2);
pDC->MoveTo(10,160+20*j);
pDC->LineTo(700,160+j*20);
pDC->SelectObject(pOldPen1);
}*/
//创建坐标
}
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView printing
BOOL CCreatePenView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CCreatePenView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CCreatePenView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView diagnostics
#ifdef _DEBUG
void CCreatePenView::AssertValid() const
{
CView::AssertValid();
}
void CCreatePenView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CCreatePenDoc* CCreatePenView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCreatePenDoc)));
return (CCreatePenDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CCreatePenView message handlers
//DDA算法生成直线
void CCreatePenView::OnDdaLine()
{
CDC* pDC = GetDC();
LineDDA2(m_ptStart.x, m_ptStart.y, m_ptEnd.x, m_ptEnd.y, pDC);
ReleaseDC(pDC);
}
//Bresenham算法生成直线
void CCreatePenView::OnBresenhamLine()
{
CDC* pDC = GetDC();
LineBres(m_ptStart.x, m_ptStart.y + 20, m_ptEnd.x, m_ptEnd.y + 20, pDC);
ReleaseDC(pDC);
}
//Bresenham生成圆弧的算法
void CCreatePenView::OnBresenhamArc()
{
CDC* pDC = GetDC();
Bre_Arc(200, 200, 200, pDC);
ReleaseDC(pDC);
}
//正负法绘圆弧
void CCreatePenView::OnPnArc()
{
CDC* pDC = GetDC();
pn_Arc(200, 200, 200, pDC);
ReleaseDC(pDC);
}
void CCreatePenView::OnMidlldepointCircle()
{
CDC* pDC = GetDC();
CircleMidpoint(300, 220, 200, pDC);
ReleaseDC(pDC);
}
void CCreatePenView::OnMidpointellipse()
{
CDC* pDC = GetDC();
EllispeMidPoint(220, 220, 100, 50, pDC);
ReleaseDC(pDC);
}
void CCreatePenView::OnLiangBarsky()
{
CDC* pDC = GetDC();
POINT ptMin, ptMax;
ptMin.x = 40, ptMin.y = 40;
ptMax.x = 400, ptMax.y = 150;
CRect rect(ptMin, ptMax);
pDC->Rectangle(&rect);
POINT p1, p2;
p1.x = 25, p1.y = 15;
p2.x = 450, p2.y = 200;
pDC->MoveTo(p1);
pDC->LineTo(p2);
ClipLine(ptMin, ptMax, p1, p2, pDC);
ReleaseDC(pDC);
}
void CCreatePenView::OnBoundaryFill()
{
CDC* pDC = GetDC();
POINT pts[5] ={{20, 20}, {20, 80}, {150, 80}, {150, 40}, {120, 20}};
pDC->Polygon(pts, 5);
BoundaryFill4(40, 40, RGB(255, 123, 0), RGB(0, 0, 0), pDC);
ReleaseDC(pDC);
}
//二维变换
void CCreatePenView::OnTransform()
{
POINT pts[4] = {50, 50, 50, 150, 150, 150, 150, 50};
POINT refPt = {100, 100}; //平移偏移量
CDC* pDC = GetDC();
pDC->Polygon(pts, 4);
m_transMatrix.Scale2(1, 0.5, refPt);
m_transMatrix.Translate2(refPt.x, refPt.y);
m_transMatrix.TransformPoints(4, pts);
pDC->Polygon(pts, 4);
ReleaseDC(pDC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -