问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

vc中实现所画风车的旋转,我用vc++6.0 cpp画了一个风车 怎么才能让它能旋转起来

发布网友 发布时间:2022-04-20 00:10

我来回答

2个回答

懂视网 时间:2022-04-20 04:31

这次给大家带来Canvas实现旋转风车的绘制,Canvas实现旋转风车绘制的注意事项有哪些,下面就是实战案例,一起来看一下。

在进行教学之前,我想聪明的你已经掌握了基本的Canvas基本操作方法,如果对Canvas还不是很了解,那么我建议你去http://www.w3school.com.cn/tags/html_ref_canvas.asp这里先熟悉一下;

okey!下图即是我们完成后的简单效果,心动不如行动,那么咱们就进行简单绘制吧!    

1、定义画布

首先我们现在html文件里面插入<canvas>标签,定义画布的尺寸,我这里定义画布的尺寸为800*600像素。同时在内部样式表里面设置canvas的背景色(方便画图时观看);

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style type="text/css">
 body{
  padding: 0;
  margin: 0;
 }
 #canvas {
  background:#5151a2;
 }
 </style>
</head>
<body>
 <canvas id="canvas" width="800" height="600"></canvas>
</body>
</html> 

接下来的核心就是在原生JS环境下,绘制风车;通过JS DOM操作方法获取到canvas元素对象,并通过getContex("2d")获取2D绘图上下文,通过这个方法就像是要告诉浏览器“我们要在这个画布上绘制2d图形”;

<script type="text/javascript">
 //获取画布的2d上下文
 var ctx = document.getElementById("canvas").getContext("2d");

2、绘制风车底座

风车的底座的几何图形看似就像一个细长细长的梯形,我们可以画出一个梯形出来,然后填充颜色,这里为了达到相对较好的效果,使用了颜色渐变填充的方法;okey!直接看代码吧~~!

 //定义一个函数 ,封装风车的底部基座
 function buttom(){
 ctx.beginPath();     //开始一条新的绘制路径
 var liner = ctx.createLinearGradient(390,600,410,600); //设置变量(颜色渐变的方向-起点-终点)
 liner.addColorStop(0,"#ccc");    //设置起点颜色
 liner.addColorStop(0.5,"#fff");    //设置中点颜色
 liner.addColorStop(1,"#ccc");    //设置终点颜色
 ctx.fillStyle = liner;     //梯形的填充方式设置为 变量(渐变颜色) 
 ctx.moveTo(395,300);     //提起我们的画笔,起点设置为(395,300)
 ctx.lineTo(405,300);     //连接起点画线
 ctx.lineTo(410,600);
 ctx.lineTo(390,600);     
 ctx.closePath();     //闭合路径
 ctx.fill();      //填充梯形
 
 }
  buttom();                              //要调用函数,才能在浏览器显示

我们来看一下页面中的效果,是不是很简单?

(我感觉我话有点多哦~!~!)

3、绘制叶子

接下来的部分将是这个动画中最关键的地方,首先我们分析一下叶子的结构,三片叶子夹角为120°,而且每片叶子的形状是相同的;他们有一个圆心,你心中或许也有疑问,先画圆心还是先画叶子?叶子的形状应该怎么画呢?叶子可不可复制粘贴呢?答案当然是可以的,Let's do it! 

思路分析:

1)、由于3片叶子的形状是一模一样,我们只需要画出一片叶子,第二第三片叶子直接copy就行了,聪明的我们是不是应该给这个叶子的画法封装一个函数呀?就叫它bind( )函数吧!!每次调用它就可以了!哎!你们TM太机智了

2)、三片叶子有一个圆心,绘制叶子的时候为了方便取坐标值,我们将圆心从画图的左上角移动梯形顶部,这样我们绘制叶子会方便很多!这里使用了translate()方法,移动坐标系!

3)、最难的一点就是理解这里动画是怎么实现的,因为动画原理会影响到我们画叶子的文档结构:

首先我们先新建一个绘图环境,我们称它为环境1,我们在环境1上画完第一片叶子;然后在 第一个绘图环境前提下  旋转120°新建第一个绘图环境2,再此基础上调用画叶子的函数bind( ),绘制二片叶子;第三片叶子的绘制方法如法炮制,在环境2的基础上旋转120°,新建环境3,调用绘制叶子函数bind( )画第三片叶子;

如果要实现动画,我们只需要旋转第一片叶子的绘图环境1,第二片叶子和第三片叶子都是参照环境1为基准画出来的,是不是也跟着动起来了呢?? 弹幕:666666

4)、最后就是一些基本的外观样式调试的啦!比如颜色渐变啊,透明度啊,之类的!

绘制叶子

画这个叶子形状的时候我是慢慢调试的,我的审美相当low,原谅我只能画出这样的叶子,当然想象力丰富的同学可以根据自己喜好来绘制,不过大体思路是一致的;

这里我声明了一个变量 var num = 0;,作为环境1旋转度数变化的一个参数: 那么咱就直接看代码吧!!!

var num =0;
function yezi(){
 ctx.save(); //保存默认情况下的canvas变换状态
 ctx.beginPath();
 ctx.translate(400,300);
 // ctx.globalAlpha = 0.9;
 // 设置第一次状态下 坐标系旋转度数
 ctx.rotate((Math.PI/180)*num);
 var liner1 = ctx.createLinearGradient(30,-12,30,12); //这里设置颜色渐变填充的样式
  liner1.addColorStop(0,"#ccc");
  liner1.addColorStop(0.5,"#fff");
  liner1.addColorStop(1,"#ccc");
  ctx.fillStyle = liner1;
 ctx.save();   //保存第一次状态 平移坐标系变换
  ctx.beginPath();
  bind();  //调用函数
  //绘制第二片叶子
  ctx.beginPath();
  ctx.rotate((Math.PI/180)*120); //坐标系旋转120°
  ctx.save();   //保存旋转坐标系状态,为第三片叶子做铺垫
  bind();  //调用函数
  //绘制第三片叶子
  ctx.beginPath();
  ctx.rotate((Math.PI/180)*120); //坐标系旋转120°
  ctx.save(); 
   bind(); //调用函数
  ctx.restore(); //回复第3次状态前(旋转坐标系)
  ctx.restore(); //回复第2次状态前(旋转坐标系)
  //绘制叶子中心圆圈
  ctx.beginPath();
  var arcgradient = ctx.createRadialGradient(0,0,0,0,0,16);
  arcgradient.addColorStop(0,"#ccc");
  arcgradient.addColorStop(0.1,"#fff");
  arcgradient.addColorStop(1,"#ccc");
  ctx.arc(0,0,10,0,Math.PI*2);
  ctx.fillStyle = arcgradient;
  ctx.fill();
 ctx.restore();  //回复第1次状态前(平移坐标系)
 num+=5; //第一状下 环境1 态坐标系旋转度数增加********************************这个num使得环境1的旋转角度在不停的变化,**********************************************
 ctx.restore();
 }
 //绘制每片叶子都重复的代码,这里做一个函数包装
 function bind(){
 ctx.moveTo(0,0);   
 ctx.quadraticCurveTo(10,-12,30,-12);    //比赛尔曲线
 ctx.lineTo(190,-3);
 ctx.quadraticCurveTo(200,0,190,3);    
 ctx.lineTo(30,12);
 ctx.moveTo(0,0);
 ctx.quadraticCurveTo(10,12,30,12);
 ctx.fill();
 }

4、设置动画

动画这部分就比较简单了,设置定时器,清除画布,调用函数;大功告成,打完收工!!!

setInterval(function(){
 ctx.clearRect(0,0,800,600);    //每次执行代码前,都要将画布清空,不然画出的图形会滞留在画布上;
 buttom();               //调用函数 
 yezi();
 },50);

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

H5如何做出碎片式的图片切换

怎样用H5计算手机摇动次数

H5调用相机拍照并压缩图片

热心网友 时间:2022-04-20 01:39

//源程序,示例代码:
// Instance_3_1_.cpp : Defines the entry point for the application.
//
/*************************************************************************
  在窗口中画一个旋转的风车,风车中有三个叶片,颜色分别为红黄和蓝,
叶片外侧有一个外接圆。
*************************************************************************/
#include <windows.h>
#include <math.h>
// 回调函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
// 初始化窗口类声明
BOOL InitWindowsClass(HINSTANCE hInstance, char *lpszClassName);
// 初始化窗口声明
BOOL InitWindows(HINSTANCE hInstance, int nCmdShow, char *lpszClassName, char *lpTitle);
WNDCLASS wndclass; // 定义一个窗口类
HWND hwnd;         // 定义一个窗口句柄
const double Pi = 3.1415926;
int nMaxNumber = 20; // 叶片循环一周中绘图的次数
int nNum = 0; // 记录当前的顺序
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       nCmdShow)
{
MSG Msg;                      // 定义消息
char lpszClassName[] = "风车"; // 窗口的类名
char lpTitle[] = "基本绘图-旋转的风车";   // 窗口标题名
// 初始化窗口类
if (!InitWindowsClass(hInstance, lpszClassName))
{
return FALSE;
}
// 初始化窗口
if (!InitWindows(hInstance, nCmdShow, lpszClassName, lpTitle))
{
return FALSE;
}
//消息循环
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam; // 程序终止时将信息返回系统
}
// 初始化窗口类定义
BOOL InitWindowsClass(HINSTANCE hInstance, char *lpszClassName)
{
//1、窗口类定义
wndclass.style = 0;             // 窗口类型为默认类型
wndclass.lpfnWndProc = WndProc; // 窗口处理函数为 WNDPROC
wndclass.cbClsExtra = 0;        // 窗口类无扩展
wndclass.cbWndExtra = 0;        // 窗口实例无扩展
wndclass.hInstance = hInstance; // 当前实例句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 窗口的最小化图标为默认图标
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);   // 窗口采用箭头光标
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 窗口采用白色背景
    wndclass.lpszMenuName = NULL; // 窗口中无菜单
wndclass.lpszClassName = lpszClassName; //类名为 lpClassName
//2、注册窗口类
if (!RegisterClass(&wndclass))
{ // 如果注册失败则发出警告声音
MessageBeep(0);
return FALSE;
}
return TRUE;
}
// 初始化窗口声明
BOOL InitWindows(HINSTANCE hInstance, int nCmdShow, char *lpszClassName, char *lpTitle)
{
//3、创建窗口
hwnd = CreateWindow(
lpszClassName, 
lpTitle, 
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 
0, 
600, 
450, 
NULL, 
NULL, 
hInstance, 
NULL
);
//4、显示窗口
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
// 回调函数定义
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC         hDC;          // 定义设备环境句柄
HPEN        hPen;         // 定义画笔句柄
HBRUSH      hBrush;       // 定义画刷句柄
PAINTSTRUCT PtStr;        // 定义包含绘制信息的结构体变量
POINT       pCenterPoint; // 定义一个圆尽心点的坐标
int         nRadious = 50;// 定义圆的半径
double      fAngle;       // 叶片的直边与水平轴的夹角
switch(message)
{
case WM_PAINT:
{ // 处理绘图消息
hDC = BeginPaint(hwnd, &PtStr);        // 得到设备句柄
SetMapMode(hDC, MM_ANISOTROPIC);       // 设置映像模式
SetWindowExtEx(hDC, 400, 300, NULL);   // 设置窗口区域(逻辑单位)
SetViewportExtEx(hDC, 600, 450, NULL); // 设置视口区域(物理单位)
SetViewportOrgEx(hDC, 300, 200, NULL); // 设置视口原点坐标为(300, 200)
// 绘制外圆
hPen = (HPEN)GetStockObject(BLACK_PEN);
SelectObject(hDC, hPen);
Ellipse(hDC, -100, -100, 100, 100);
// 绘制风车的叶片
// 1、画红色叶片
hBrush = CreateSolidBrush(RGB(255, 0, 0)); 
SelectObject(hDC, hBrush);
fAngle = 2 * Pi / nMaxNumber * nNum;
pCenterPoint.x = (int)(nRadious * cos(fAngle));
pCenterPoint.y = (int)(nRadious * sin(fAngle));
Pie(
hDC, 
pCenterPoint.x - nRadious, pCenterPoint.y - nRadious, 
pCenterPoint.x + nRadious, pCenterPoint.y + nRadious, 
(int)(pCenterPoint.x + nRadious * cos(fAngle)),
(int)(pCenterPoint.y + nRadious * sin(fAngle)), 
(int)(pCenterPoint.x + nRadious * cos(fAngle + Pi)), 
(int)(pCenterPoint.y + nRadious * sin(fAngle + Pi))
);
// 2、画天蓝色叶片
hBrush = CreateSolidBrush(RGB(255, 255, 0)); 
SelectObject(hDC, hBrush);
pCenterPoint.x = (int)(nRadious * cos(fAngle + 2 * Pi / 3));
pCenterPoint.y = (int)(nRadious * sin(fAngle + 2 * Pi / 3));
Pie(
hDC, 
pCenterPoint.x - nRadious, pCenterPoint.y - nRadious, 
pCenterPoint.x + nRadious, pCenterPoint.y + nRadious, 
(int)(pCenterPoint.x + nRadious * cos(fAngle + 2 * Pi / 3)), 
(int)(pCenterPoint.y + nRadious * sin(fAngle + 2 * Pi / 3)), 
(int)(pCenterPoint.x + nRadious * cos(fAngle + Pi + 2 * Pi / 3)),
(int)(pCenterPoint.y + nRadious * sin(fAngle + Pi + 2 * Pi / 3))
);
// 2、画*叶片
hBrush = CreateSolidBrush(RGB(0, 255, 255)); 
SelectObject(hDC, hBrush);
pCenterPoint.x = (int)(nRadious * cos(fAngle + 4 * Pi / 3));
pCenterPoint.y = (int)(nRadious * sin(fAngle + 4 * Pi / 3));
Pie(
hDC, 
pCenterPoint.x - nRadious, pCenterPoint.y - nRadious, 
pCenterPoint.x + nRadious, pCenterPoint.y + nRadious, 
(int)(pCenterPoint.x + nRadious * cos(fAngle + 4 * Pi / 3)), 
(int)(pCenterPoint.y + nRadious * sin(fAngle + 4 * Pi / 3)), 
(int)(pCenterPoint.x + nRadious * cos(fAngle + Pi + 4 * Pi / 3)),
(int)(pCenterPoint.y + nRadious * sin(fAngle + Pi + 4 * Pi / 3))
);
nNum++; // 当前充数增加1
Sleep(50); //等待0.1秒
InvalidateRect(hwnd, NULL, 1); // 重绘窗口区域
DeleteObject(hPen);
DeleteObject(hBrush);
EndPaint(hwnd, &PtStr);
break;
}
case WM_DESTROY:
{
// 调用 PostQuitMessage 发出 WM_QUIT 消息
PostQuitMessage(0);
}
default:
{
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
return 0;
}

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
上海大名城映_有多少户? 英特尔处理器漏洞有哪些害? 英特尔漏洞都会影响哪些CPU?下一代还会影响吗? cpu使用率100%是怎么回事呀? 生姜红茶减肥法骗局 鲁东大学大一新生电话卡是用的学校发的联通卡吗? 鲁东大学用移动的多还是用联通的多?求师哥师姐们解答 ...牙齿一碰到溃疡就疼,治疗口腔溃疡的偏方有哪些呢? 我想找一个飞车情侣名字,我有车队,车队名字是丿茗门丨灬 梦幻悟空传变态版安卓APK 自动档的车电瓶没电可以推着火吗 自动挡车没电了可以推吗 自动挡的车电瓶没电能推动发动吗 话说自动挡的车,没电能推着车吗 四川省广元市党政网 自动挡汽车,如果电瓶没电不能启动,可以推车吗? 四川省广元市朝天区的特产是什么? 广元市朝天区羊木镇西北乡乡长是谁 三网通的手机可以两个移动卡吗 朱国勇的个人履历 广元山为何如此火? 三网通双卡双待手机能支持 同一运营商的卡吗? 广元市长是哪里人 华为g6三网通手机可以上两张电信卡吗 吴连奇的履历 朝天区的旅游景点 张国辉的简介 广元曾经是否有一位姓卢的副市长或者秘书长 vivox6三网通能不能上两张电信卡 三网通手机能同时用二个电信卡吗??? 股债同屏怎么设置 怀集县众诚汽车贸易有限公司怎么样? 电瓶车投币充电桩电压是多少里面电线怎连接? 陈仓区的区划 汶川地震感人事迹(短小,而又能讲清楚事情的起因经过结果) 想知道: 滁州市 二龙乡谭村 在哪 求汶川大地震中感人的故事 作文:地震中的爱 哺乳期能喝白扁豆煲汤吗 白扁豆泡开水喝是用生的还是炒过的 白扁豆、芡实、红小豆、薏米能一起煮粥喝吗 ipodtouch里的视频歌曲 如何把在电脑里的音乐和视频拉到itouch里面 请问大家,我买了ipodtouch,能否把电脑里的音乐倒到ipodtouch里面呢? 和新电脑上的itunes同步,怎样才能把原来itouch、ipod里的音乐保留,再添加新的音乐进去? 盐,碱,矾炸油条怎么用法 - 信息提示 哪里有WAV格式的音乐下载! WAV格式音乐在哪下载较好?320KMP3的呢? 哪里下载WAV格式的音乐