在前边博文“向量学习1”中,介绍了在篮球游戏中,防守者逼近防守投篮者,如何用向量,计算逼近的方向以及前进的距离。方法可用篮球投篮、足球射门和射击的子弹轨迹等等方面。在pygame游戏中,可能图形围绕自己中心旋转;也可能象地球围绕太阳那样,图形围绕远处某点旋转;也可能象坦克炮那样旋转,线形图形以线端点为中心旋转。本文用例子说明用向量实现的方法。首先介绍图形围绕图形自己中心旋转。见下边代码。

p=pygame.image.load("L1.png").convert_alpha()
rect=p.get_rect(center=(150,100))
p1=pygame.transform.rotate(p,10)      #将p图旋转10度,返回旋转后的Surface实例
r=p1.get_rect(center=rect.center)        #如注释此条语句
screen.blit(p1, r)                     #同时注释此条语句
#screen.blit(p1,(150,100))             #改为此条语句,将发生抖动

其中第3条语句将p图以p图中心点为旋转中心旋转10度,返回旋转后的Surface实例p1。请注意,每次返回的p1图的中心点可能不重合,为了使图形在原位置显示,第4条语句将p1中心点修改为p图中心点。如按照注释修改,去掉两句,增加一句,在连续旋转时,就会看到图形抖动。本例使用两个图形作为旋转对象,如下图,一条水平线,一个圆,为了看到圆转动,圆有1个突起。后边要用到,凸起和x轴夹角为0。

实际例子完整程序如下。

import pygame
bgcolor = pygame.Color('blue')
pygame.init()
size = width, height = 400,300
screen = pygame.display.set_mode(size)
pygame.display.set_caption("原地旋转")
p=pygame.image.load("c.png").convert_alpha()
rect=p.get_rect(center=(150,100))
fclock = pygame.time.Clock()
fps = 10
angle=0
running = True
while running:    for event in pygame.event.get():if event.type == pygame.QUIT:running = False        screen.fill(bgcolor)angle+=10p1=pygame.transform.rotate(p, angle)                r=p1.get_rect(center=rect.center)     #如注释此条语句                        screen.blit(p1, r)                    #同时注释此条语句#screen.blit(p1,(150,100))            #改为此条语句,将发生抖动pygame.display.flip()                           fclock.tick(fps)
pygame.quit()

3张效果图如下。第1图旋转的图形是圆,第2图是一条水平线段,两图都没有抖动。在第3图可看到水平线段有明显抖动。从第2图可以验证是以图形中心点为旋转中心完成旋转。



如果希望图形象地球绕太阳那样旋转,也就是图形旋转中心不是图形中心点,而是图形外某点,这就需要向量的概念。为了看懂下边论述,有必要解释“向量”和“有向线段”概念。数学意义上的向量,只有方向和长度,向量的位置是没有意义的。但实际上,在程序中处理的向量是在游戏坐标系中的有向线段,位置还是必要的。可以这样理解,有向线段是指定了位置的向量,因此,向量的许多概念和方法也适用于有向线段,下边论述中的向量一般是指有向线段。首先看下边两条语句。

v=pygame.math.Vector2(100,0)
v1 = v.rotate(angle)

第1条语句建立从(0,0)到(100,0)的向量v,该向量和x轴夹角为0,即向量角度为0,长度为100。第2条语句的旋转中心为(0,0),即围绕(0,0)旋转指定角度,旋转后产生新向量v1,起点不变,还是(0,0)。如果每帧中,v向量旋转某角度得到v1后,都把图形放到v1向量头部显示,连续重复这两个动作,就看到图形围绕(0,0)旋转。但问题是pygame游戏坐标,x轴向右为正,y轴向下为正,而且x和y只取正值,即只要x或y有一个为负,图形就不可见,如果围绕(0,0)旋转,只有1/4可见,其余不可见。为此,可把实际的旋转中心移动屏幕中央,例如(240,180)。具体办法是:每次v围绕(0,0)旋转指定角度后,平移v1向量起点到(240,180)为v2,把图形放到v2向量头部显示,每帧中连续重复这两个动作,就看到图形围绕(240,180)旋转了。
那么如何平移向量呢?数学上一条线段,其起点和终点x或y坐标都增加同一个值,生成新线段,例如x都加240,y加180,则这两条线段平行,也就是平移了向量。猜想平移v1到(240,180)可能程序表达式是:v2=(240,180)+v1。为此做了验证,见下图。图中r,a=v.as_polar()是得到向量v的长度r及方向即和x轴夹角。执行了v1=(240,180)+v后,向量v和v1的长度和角度都相同,只是头部终点不同,说明该表达式确实实现了平移。

注意,按上述方法平移后,向量起点总是(240,180)保持不变,向量终点由于旋转,总在变化。也就是说,平移后,图形围绕(240,180)点旋转。总结一下,(240,180)点是旋转中心,v向量长度100是旋转半径。一般使图形中点(center)移到向量的终点。完整程序如下,使用的图像是有凸起的圆。

import pygame
bgcolor = pygame.Color('blue')
pygame.init()
size = width, height = 480,360
screen = pygame.display.set_mode(size)
pygame.display.set_caption("圆围绕某点旋转")
p=pygame.image.load("c.png").convert_alpha()
length=100                     #旋转半径
#length=p.get_rect().width//2
v=pygame.math.Vector2(length,0)#从(0,0)到(length,0)的向量,此时旋转中心为(0,0)
c=(240.0,180.0)                     #以后将要设置的旋转中心
fclock = pygame.time.Clock()
fps = 10
angle=0
running = True
while running:    for event in pygame.event.get():if event.type == pygame.QUIT:running = Falsescreen.fill(bgcolor)        #背景颜色angle-=5                    #正数是顺时针,负数是逆时针p1=pygame.transform.rotate(p, -angle+180)     #使圆突出部分指向圆心v1 = v.rotate(angle)    #有向线段v1旋转,起点不变为(0,0),终点旋转,坐标改变#下句等式右侧将v1平移,x轴方向右移240,y轴方向下移180,有向线段起点为(240,180)a,b=c+v1      #因此旋转中心不变,终点旋转,坐标改变,(a,b)是平移后向量顶点坐标#v2=c+v1                #此句也正确,坐标元组+向量使向量v1平移到v2#r=p1.get_rect(center=(240,180)+v1)#使用此句提示将来版本可能不支持默认类型转换r=p1.get_rect()         #改为下边两句,将图形移到平移后向量顶点r.center=(int(a),int(b))        screen.blit(p1, r)      #在新位置显示图形pygame.display.flip()                           #刷新游戏场景fclock.tick(fps)#fps是每秒多少帧,减去程序运行时间,为实现fps,还需延迟时间
pygame.quit()
#a=v.angle_to(v1)#两个向量之间的夹角

效果图如下。

凸起的圆围绕(240,180)点旋转,按以上叙述,圆的凸起应该指向x轴正方向保持不变,但实际效果是这个圆的凸起总是指向圆心。这是因为有如下语句:

angle-=5                             #angle是向量每帧旋转角度
p1=pygame.transform.rotate(p, -angle+180)     #使圆突出部分指向圆心
v1 = v.rotate(angle)                #向量旋转给定角度

其中第2句使图形p(即圆)旋转了一个角度,使圆突出部分指向圆心。这个角度如何得到的呢?首先向量的初始位置角度为0,同样圆的凸起和x轴夹角也为0(见最上边的图形中的圆),两者同向。在这个位置,要让圆的凸起指向圆心,必须旋转180度,如向量再旋转angle,凸起的圆也要自转(-angle+180),这样使圆的凸起总是指向圆心。
最后解决使线形图形以线端点为中心,象坦克炮那样旋转。前边提到v向量长度100是旋转半径,只要修改v向量长度等于要旋转图形宽度一半,在使线形图形水平摆放,即和x轴夹角为0即可,本程序只要把上述程序第9条语句注释去掉即可,并将程序第9条语句的图形文件名称改为线段图形名称:L1.png即可。效果图如下。

向量学习2:图形围绕自己中心旋转、围绕图形外或内任意点为中心旋转相关推荐

  1. c 语言drawtext字体旋转,C# GDI+文字画图 添加任意角度文字(文字旋转是中心旋转,角度顺时针为正)...

    public Bitmap AddText(string DrawText) { Bitmap bmp = new Bitmap(350, 300); Graphics g = Graphics.Fr ...

  2. 计算机图形学 学习笔记(七):二维图形变换:平移,比例,旋转,坐标变换等

    接上文 计算机图形学 学习笔记(六):消隐算法:Z-buffer,区间扫描线,Warnock,光栅图形学小结 在图形学中,有两大基本工具:向量分析,图形变换.本文将重点讲解向量和二维图形的变换. 5. ...

  3. 【OpenCV 例程200篇】27. 图像的旋转(以任意点为中心)

    [OpenCV 例程200篇]27. 图像的旋转(以任意点为中心) 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 图 ...

  4. 图形图像处理-之-任意角度的高质量的快速的图像旋转 上篇 纯软件的任意角度的快速旋转

    (2009.03.09  可以到这里下载旋转算法的完整的可以编译的项目源代码:  http://blog.csdn.net/housisong/archive/2009/03/09/3970925.a ...

  5. R语言学习笔记——入门篇:第三章-图形初阶

    R语言 R语言学习笔记--入门篇:第三章-图形初阶 文章目录 R语言 一.使用图形 1.1.基础绘图函数:plot( ) 1.2.图形控制函数:dev( ) 补充--直方图函数:hist( ) 补充- ...

  6. d3.js 旋转图形_公考行测图形推理类题目答题技巧

    公务员考试的判断推理考查的内容有三个,分别是图形推理.逻辑判断和时间排序.接下来就为大家分享图形推理常见六种题型,分别为位置类.属性类.数量类.黑白块.字母类.样式类. 一.位置类 位置类图形推理主要 ...

  7. 深度学习(四十二)word2vec词向量学习笔记

    word2vec词向量学习笔记 原文地址:http://blog.csdn.net/hjimce/article/details/51564783 个人微博:黄锦池-hjimce 一.使用原版word ...

  8. matlab中如何转动三维图_MATLAB小技巧之:绕任意空间轴旋转三维图形

    x=1:0.1:10; y=sin(x); c=cosd(15); s=sind(15); X=x*c-y*s; Y=x*s+y*c; plot(x,y) hold on plot(X,Y) 这就是新 ...

  9. matlab 使得三维图形可以手动旋转,三维图形的平移,旋转与错切

    1.平移变换 三维图形的平移变换可以描述为: %% 圆的平移,x加1,y加1,z+1 clc;clear all; figure(1); axis equal; sphere(50);%球由50*50 ...

最新文章

  1. Docker安装weblogic(五)
  2. 2015各地高温补贴发放标准时间一览表
  3. python竞赛_浅谈Python在信息学竞赛中的运用及Python的基本用法
  4. (原创)惠州市惠阳区房价偏低的原因深入分析
  5. 【开源项目之路】jquery的build问题
  6. 51nod 1851 俄罗斯方块(思维题)
  7. Bootstrap 警告块
  8. Scrum立会报告+燃尽图(十月二十二日总第十三次)
  9. 前端面试题集锦(二)之CSS部分
  10. 浅谈2011年上半年Java游戏领域动态
  11. bzoj千题计划254:bzoj2286: [Sdoi2011]消耗战
  12. java中如何生成对外的接口_Java利用Swagger2自动生成对外接口的文档
  13. 转转首席架构师 孙玄:如何成为一个有情怀的工程师?
  14. 卷积神经网络原理解析
  15. open SUSE 查看本机ip地址
  16. 网络挖掘初探索(2)_NEO4J图可视化
  17. 【业务安全-01】业务安全概述及测试流程
  18. BLE4.0广播连接过程的底层剖析
  19. 微信小程序微商城(五):动态API实现商品详情页(下)
  20. 这一次我要真正学会C语言

热门文章

  1. Unity2d学习笔记(一)添加角色地图并且实现人物移动
  2. 从装大象中我们学会了什么设计模式
  3. 车牌识别github资源
  4. 深入操作系统底层分析nginx网络请求及响应过程
  5. Android音乐播放器开发(3)—注册
  6. 2021年中国互联网网民规模及互联网普及率情况:网民总体规模持续增长,城乡地区互联网普及率差异减小[图]
  7. 关于Flask框架中启动Scrapy爬虫框架时的几种问题的解决
  8. 程序设计与算法(一)第7周测验(2019夏季)
  9. derby数据库连接操作
  10. 又火了一个,看小说也能学 JavaScript?