简单的MFC画正弦曲线

1. MFC 单文档 如何画正弦曲线

1.画笔类,CPen,创建画笔类的对象后,需要调用CreatePen(......)函数创建画笔。然后将其选入设备描述表中。

pDC->SelectObject(.......);

2.设置起点坐标。在这里调用一个函数来设置坐标原点。

pDC->SetViewportOrg(100,255);

3.调用LineTo(point),MoveTo(Point)函数画图。

4.删除创建的画笔对象。pen.DeleteObject();

以下是今天所写的画正弦函数的图像。创建一个单文档的应用程序。并且在VIEW类中的OnDraw(。。。。)函数里面做消息响应。由于调用了sin()函数,所以要把math.h头文件包含进来。#include "math.h"

void CDrawSinXView::OnDraw(CDC* pDC)
{
CDrawSinXDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//建立画笔
CPen pen_Zuobixi,pen_sinx;
pen_Zuobixi.CreatePen(PS_SOLID,4,RGB(0,0,0));
pen_sinx.CreatePen(PS_SOLID,2,RGB(0,0,255));
pDC->SelectObject(&pen_Zuobixi);
//指定原点
pDC->SetViewportOrg(100,255);
pDC->SetTextColor(RGB(255,0,0));
//绘制横坐标
CString sPIText[]={"-1/2π","","1/2π","π","3/2π","2π","5/2π","3π","7/2π","4π","9/2π","5π"};
int n=-1;
int nTemp=0;
while (nTemp<=660)
{
   pDC->LineTo(60*n,0);
   pDC->LineTo(60*n,-5);
   pDC->MoveTo(60*n,0);
   pDC->TextOut(60*n-sPIText[n+1].GetLength()*3,16,sPIText[n+1]);

   n++;
   nTemp +=60;
}
pDC->MoveTo(0,0);
CString strTemp;
//绘制纵坐标
for(n=-4,nTemp = 0;nTemp<=180;n++,nTemp+=60)
{
   pDC->LineTo(0,60*n);
   pDC->LineTo(5,60*n);
   pDC->MoveTo(0,60*n);
   strTemp.Format("%d",-n);
   pDC->TextOut(10,60*n,strTemp);
}
   double y,radian;
pDC->SelectObject(&pen_sinx);
for(int x=-60;x<600;x++)
{
   //弧度=X坐标/曲线宽度*角系数*π
   //Y坐标=振幅*曲线宽度*sin(弧度)
   radian =x/((double)60*2)*PI;
   y=sin(radian)*2*60;
   pDC->MoveTo((int)x,(int)y);
   pDC->LineTo((int)x,(int)y);
}
pen_sinx.DeleteObject();
pen_Zuobixi.DeleteObject();

}

 

http://www.360doc.com/content/14/1127/22/11539950_428607967.shtml

 

2. 做一个振幅可以改变的正弦曲线的vc小程序,但是坐标轴可以画出来,正弦曲线出不来,高手给分析一下程序吧~

void CSinxDlg::OnBtn() 
{
// TODO: Add your control notification handler code here
CWnd* pWnd=GetDlgItem(IDC_SRC);
CDC* pDC=pWnd->GetDC();

pDC->Rectangle(0,0,400,300);

CPen redpen(PS_SOLID,1,RGB(255,0,0));
CPen* pOldPen=pDC->SelectObject(&redpen);
pDC->MoveTo(20,10);
pDC->LineTo(20,290);
pDC->MoveTo(20,150);
pDC->LineTo(380,150);

CString sPIText[]={"0","1/2π","π","3/2π","2π","5/2π","3π"};

for (int i=0;i<7;i++)
{
pDC->MoveTo(60*i+20,150);
pDC->LineTo(60*i+20,145);
pDC->TextOut(60*i+15,153,sPIText[i]);
}

CString sYText[]={"-2","-3/2","-1","-1/2","","1/2","1","3/2","2"};
for (int j=0,m=0;m<9;j++,m++)
{
pDC->MoveTo(20,250-25*j);
pDC->LineTo(23,250-25*j);
pDC->TextOut(5,250-25*j,sYText[m]);
}
pDC->SelectObject (pOldPen);

double radian,y;
UpdateData();
double m_pi;
m_pi=m_radius;
for (i=20;i<380;i++)
{
radian=(i-20)/((double)60*2)*PI;
y=150-sin(radian)*50*m_pi;
pDC->MoveTo(i,(int)y);
pDC->LineTo(i,(int)y);
}
}

小弟明白了,其实最后两句:
 pDC->MoveTo(i,(int)y);
 pDC->LineTo(i,(int)y);
进行画线的时候是显示的正弦曲线上的一些点,但是此时系统画笔的宽度为1,当画笔宽度为1时,是不显示绘制的每个点的,当把画笔的宽度改为2或者更大的时候就可以显示啦~

http://bbs.csdn.net/topics/340031505

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
// ChildView.cpp : CChildView 类的实现 // #include "stdafx.h" #include "12222222222222222222张三.h" #include "ChildView.h" #include "ParaDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CChildView CChildView::CChildView() { } CChildView::~CChildView() { } BEGIN_MESSAGE_MAP(CChildView, CWnd) ON_WM_PAINT() ON_COMMAND(ID_SET_PARA, &CChildView::OnSetPara) ON_COMMAND(ID_SIN_GO, &CChildView::OnGo) ON_COMMAND(ID_SIN_BACK, &CChildView::OnBack) ON_COMMAND(ID_SIN_STOP, &CChildView::OnStop) ON_WM_TIMER() END_MESSAGE_MAP() // CChildView 消息处理程序 BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) { if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE; cs.style &= ~WS_BORDER; cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast(COLOR_WINDOW+1), NULL); return TRUE; } void CChildView::OnPaint() { CPaintDC dc(this); // 用于绘制的设备上下文 // TODO: 在此处添加消息处理程序代码 // 不要为绘制消息而调用 CWnd::OnPaint() m_Sin.Draw(&dc); } void CChildView::OnSetPara() { // TODO: 在此添加命令处理程序代码 CParaDlg dlg(m_Sin.m_iA, m_Sin.m_iF, m_Sin.m_iP); if(IDOK == dlg.DoModal()) { m_Sin.m_iA = dlg.m_iA; m_Sin.m_iF = dlg.m_iF; m_Sin.m_iP = dlg.m_iP; RedrawWindow(); } } void CChildView::OnGo() { SetTimer(1000,50,NULL);//响应一个图标按下时打开一个 ID 为 1000 的定时器,周期50ms KillTimer(2000); } void CChildView::OnBack() { SetTimer(2000,50,NULL);//响应一个图标按下时打开一个 ID 为 1000 的定时器,周期50ms KillTimer(1000); } void CChildView::OnStop() { KillTimer(1000);//响应停止图标按下时关掉 ID 为 1000 的定时器 KillTimer(2000);//响应停止图标按下时关掉 ID 为 2000 的定时器 } void CChildView::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 switch (nIDEvent)//判断响应的是哪个定时器 { case 1000: m_Sin.m_iP --;//动作 break; case 2000: m_Sin.m_iP ++;//动作 break; } RedrawWindow();//上面的动作只是改变了参数,这里是重窗口,展示动作 CWnd::OnTimer(nIDEvent); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值