-
用python绘制散点图
2018-07-13 21:41:53今天下午学习了如何使用python绘制简单的散点图,写成博客分享一下。 在python中画散点图主要是用matplotlib模块中的scatter函数,先来看一下scatter函数的基本信息。 网址为:点击打开链接 可以看到scatter中有很多...在python中画散点图主要是用matplotlib模块中的scatter函数,先来看一下scatter函数的基本信息。
网址为:点击打开链接
可以看到scatter中有很多参数,经常使用的参数主要有以下几个:
c:
marker:
数据、代码和绘制的图如下。
数据(取第一列作为x,取第四列作为y)截图:
代码如下:
import matplotlib.pyplot as plt import numpy as np # 定义画散点图的函数 def draw_scatter(n, s): """ :param n: 点的数量,整数 :param s:点的大小,整数 :return: None """ # 加载数据 data = np.loadtxt('results.txt', encoding='utf-8', delimiter=',') # 通过切片获取横坐标x1 x1 = data[:, 0] # 通过切片获取纵坐标R y1 = data[:, 3] # 横坐标x2 x2 = np.random.uniform(0, 5, n) # 纵坐标y2 y2 = np.array([3] * n) # 创建画图窗口 fig = plt.figure() # 将画图窗口分成1行1列,选择第一块区域作子图 ax1 = fig.add_subplot(1, 1, 1) # 设置标题 ax1.set_title('Result Analysis') # 设置横坐标名称 ax1.set_xlabel('gamma-value') # 设置纵坐标名称 ax1.set_ylabel('R-value') # 画散点图 ax1.scatter(x1, y1, s=s, c='k', marker='.') # 画直线图 ax1.plot(x2, y2, c='b', ls='--') # 调整横坐标的上下界 plt.xlim(xmax=5, xmin=0) # 显示 plt.show() # 主模块 if __name__ == "__main__": # 运行 draw_scatter(n=2000, s=20)
绘制的图如下:
-
自己绘制菜单
2015-06-11 13:03:18自己绘制菜单 -
【AD】Altium Designer 原理图的绘制
2018-05-18 09:38:42在原理图的绘制过程中,各个元件的大小是不能调整的。如果原理图纸张放不下,需要对图纸进行设置:设计->文档选项,右键->选项->文档选项。 同时,在原理图的绘制过程中,为了效率和正确性...软件版本:Altium Designer 14
原理图设置基础
原理图的设置
在原理图的绘制过程中,各个元件的大小是不能调整的。如果原理图纸张放不下,需要对图纸进行设置:设计->文档选项,右键->选项->文档选项。
同时,在原理图的绘制过程中,为了效率和正确性,往往与环境参数的设置有关。设置原理图工作环境:工具->设置原理图参数,右键->选项->设置原理图参数。
在弹出的窗口中,可以进行常规设置、图形编辑、鼠标滚轮设置、编译器、自动获得焦点、库扩充方式、栅格、断开连线、默认单位、默认图元、端口操作选项卡可以进行设置。
加载元件库
在进行原理图的绘制,首先需要在图纸上放置需要的元件符号。Altium Designer的元件库中能够找到一般常用的电子元件,用户只需要在元件库中查找到所需的元件符号,并放置在图纸的适当位置即可。
元件库的后缀名有哪些,区别是什么?
在Altium Designer中经常遇到的后缀是.SCHLIB,.PCBLIB,.INTLIB三种。
其中,.SCHLIB为原理图中的电子元件,.PCBLIB为PCB图中的电子元件,.INTLIB整合了两者并将它们相对应起来。
怎么打开“库”面板呢?
只需要将光标箭头放置在工作窗口右侧“库”标签上,就会自动弹出“库”面板。如果在工作窗口右侧没有“库”标签,单击底部面板控制栏中的“System”,选中“库...”,就会自动弹出“库”面板。
默认Altium Designer已经加载了两个元件库,如果其中没有自己想要的元件,就需要加载元件库。
加载元件库的方法:库”面板->Libraries,在弹出的窗口直接操作就行了。
放置元件
Altium Designer原理图的绘制主要是有两个要素:元素符号和线路连接。绘制原理图的主要操作就是将元件符号放置在原理图图纸上,然后用线将元件符号中的引脚连接起来,建立正确的电气连接。
首先,Altium Designer提供了强大的元件搜索能力:“库”面板->Search,弹出搜索库的对话框。
该查找元件功能,可以在范围中选择Components(元件)、Protel Footprints(PCB封装)、3D Models(3D模型)和Database Components(数据库元件)四种查找类型。
在元件库中找到了元件之后,就可以在原理图中放置该元件了。操作也十分简单:在“库”面板上选中元件,直接拖动到想要的位置,松开鼠标即可。
移动/旋转元件
当想要移动或者旋转元件,首先就要先选中电气节点。在Altium Designer中选中电气节点的方式是:将光标指向需要移动的元件(不需要点击),按住鼠标左键不放,此时光标会移动到元件的电气节点上,之后就可以进行移动和旋转操作了。
- 移动:选中元件的电气节点,按住鼠标左键不放,拖动元件到指定的位置,释放鼠标左键;
- 旋转:选中元件的电气节点,按住鼠标左键不放,在键盘上点击功能键,实现旋转的操作,释放鼠标左键。
旋转功能键 功能键名称 描述 space键 逆时针旋转90° shift+space键 顺时针旋转90° x键 左右对调 y键 上下对调 设置元件属性
在原理图上放置的所有原件都具有自身的特定属性,每放置好一个元件之后,应该对其的属性进行正确的设置。元件属性设置具体包含元件的基本属性设置、元件的扩展属性设置、元件的模型设置、元件引脚编号等。比如说:电容的大小,电阻的大小等等。
怎么来进行元件属性的设置呢?双击需要修改的元件。
例如:放置一个电阻元件,设置它的属性(电阻的编号和电阻值):
原理图的绘制
在图纸上放置好电路设计需要的各种元件并对它们的属性进行设置之后,就可以根据电路的具体要求,将各个元件连接起来,以建立并实现电路的实际连通性。这里的连通,指的是具有电气意义的连接,即电气连接。
电气连接有两种实现方式:一种是“物理连接”,即直接使用导线将各个元件连接起来;另一种是“逻辑连接”,即不需要实际的连线操作,而是通过设置网络标号使元件之间具有电气连接关系。
原理图连接工具
Altium Designer提供了三种对原理图进行连接操作的方法:放置菜单栏下的命令、布线工具栏、快捷键。
放置导线
导线是电气连接中最基本的组成单位,放置导线的方法:放置->线,布线工具栏
按钮。
如果要连接的两个引脚不在同一水平线或者同一垂直线上,则需要在放置导线的过程中点击确定导线的拐弯位置。同时,导线的拐弯模式也可以分成三种:直角、45°角、任意角度。可以通过shift+space键来进行相互之间的切换。
放置总线
总线是一组具有相同性质的并行信号线的组合,如数据总线、地址总线、控制总线等的组合。在大规模的原理图的设计,尤其是数字电路的设计中,如果只用导线来完成各元件之间的电气连接,那么整个原理图的连线就会变得杂乱和繁琐。而总线的使用就会大大简化原理图的连线操作。
放置总线的方法:放置->总线,布线工具栏
按钮。
总线入口是单一导线和总线的连接线。使用总线入口把总线和具有电气特性的导线连接起来,可以使电路图更加美观、清晰。与总线一样,总线入口也不具有任何电气连接的意义,而且它的存在也不是必须的。即使不通过总线入口,直接把导线与总线连接也是正确的。
放置总线入口的方法:放置->总线入口,布线工具栏
按钮。
放置手工接点
在Altium Designer中,默认情况下,导线会在T形交叉点处自动放置电气节点,表示所画线路在电气意义上是连接的。但是在其他的情况下,如十字交叉点处,由于系统无法判断导线是否连接,就不会放置电气节点。如果导线是互相连接的,就需要自己手动放置电气节点。
放置手工接点的方法:放置->手工接点。
放置电源和接地符号
电源和接地符号是电路原理图中必不可少的组成部分。
放置电源和接地的方法:布线工具栏
按钮。
放置网络标签
元件之间的电气连接除了直接使用导线之外,还可以用相同的网络标号来完成。
放置网络标签的方法:放置->网络标签,布线工具栏
按钮。
放置离图连接
在原理图编辑环境中,离图连接的作用其实和网络标签是一样的,不同的是,网络标签使用在同一张原理图中,而离图连接用在同一工程文件下不同的原理图。
放置离图连接的方法:放置->离图连接。
使用绘图工具绘图
在原理图编辑环境中,与布线工具栏相对应的,还有一个实用工具栏,用于在原理图中绘制各种标注信息,使电路原理图更清晰,数据更完整,可读性更强。
该实用工具栏中的各种图元均不具有电气连接特性,不会被添加到网络表数据中。
使用绘图工具绘图的方法:放置->绘图工具,实用工具栏
按钮。
原理图的后续处理
网络表
在由原理图生成的各种报表中,网络表是最为重要的。所谓网络,指的是彼此连接在一起的一组元件引脚,一个电路实际上就是由若干个网络组成的。而网络表就是对电路或者电路原理图的一个完整描述,描述的内容包括两个方面:
- 电路原理图中的所有元件的信息(包括元件标识、元件引脚、PCB封装形式等等);
- 网络的连接信息(包括网络名称、网络节点等)。
这些都是进行PCB布线、设计PCB印刷电路板不可缺少的依据。
具体来说,网络表包括两种:一是基于单个原理图文件的网络表,另一个是基于整个项目的网络表。
网络表的选项设置
工程->工程参数->Options,打开选项卡:
在里面可以设置各种报表(包括网络表)地输出路径,默认是当前文件夹下。
创建网络表
由于网络表有两种形式,因此在创建上也是有所不同:
- 基于单个原理图文件的网络表:设计->工程的网络表->PCAD;
- 基于整个项目的网络表:设计->文件的网络表->PCAD。
到网络表的输出路径中,会发现网络表文件。网络表的默认后缀名为.NET,它是一个简单的ASCII码文本文件,由多行文本组成。内容分成两大部分:一部分是元件的信息,一部分是网络信息。
元件信息由若干小段组成,每一个元件的信息为一小段,用大括号分割开来。而每一个元件由元件封装、元件标识、元件管脚等组成。比如:
红色框出来的部分从上到下,从左到右依次为:元件封装、元件标识、元件管脚。
网络信息由若干小段组成,每一个网络的信息为一小段,用大括号分割开来。而每一个网络由网络名称和网络中具有电气连接关系的元件引脚等组成。
-
使用 canvas 和面向对象思想绘制流星动画
2020-12-13 18:06:56本人也是前端小白,正在努力学习的路上奔跑~最近看到一位博主大大的绘制星空博文,加上最近对面向对象编程思想的理解,也照葫芦画瓢复现了一个demo,顺便熟悉一下canvas的一些API。 源代码 <!DOCTYPE html> &...本人也是前端小白,正在努力学习的路上奔跑~最近看到一位博主大大的绘制星空博文,加上最近对面向对象编程思想的理解,也照葫芦画瓢复现了一个demo,顺便熟悉一下canvas的一些API。
源代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>StarSky</title> </head> <body></body> <style> * { margin: 0; padding: 0; width: 100vw; height: 100vh; overflow: hidden; } </style> <script> /** * © WindyZ write in 2020 * 进度表 * 1125 完成初始化方法以及相关参数 * 完成绘制背景,以及窗口大小改变的监听 * 1126 完成月亮绘制,修复窗口大小监听无效的问题 * 1127 完成星星绘制,未解决月亮周围减少星星问题 * 1201 完成流星绘制,抽象出 Star 和 Commet 类 * 1211 完成山体绘制,完成大体的动画 */ // 星星类 class Star { x = 0; // x 坐标 y = 0; // y 坐标 opacity = 0; // 星星透明度 radius = 0; // 星星半径 is_weak = true; // 星星闪烁的时候,透明度是否先减小到0,再增加到1 constructor(width, height, moon_radius) { this.init(width, height, moon_radius); } init(w, h, m_r) { this.x = Math.random() * w; this.y = Math.random() * h * 0.8; this.x >= w / 9 - m_r && this.x <= w / 9 + m_r * 3 ? (this.x = this.x + (Math.random() >= 0.5 ? -m_r * 2 : m_r * 2)) : ""; this.y >= h / 9 - m_r && this.y <= h / 9 + m_r * 3 ? (this.y = this.y + (Math.random() >= 0.5 ? -m_r * 2 : m_r * 2)) : ""; this.opacity = Math.random() * 1.1; this.radius = Math.random() * 0.8 + 0.5; } // 获得参数 get getStarVal() { return { x: this.x, y: this.y, opacity: this.opacity, radius: this.radius, is_weak: this.is_weak, }; } // 更改参数 setStarVal(val) { if (!!val) { for (let key in val) { if (key == "x") { this.x = val[key]; } if (key == "y") { this.y = val[key]; } if (key == "opacity") { this.opacity = val[key]; } if (key == "radius") { this.radius = val[key]; } if (key == "is_weak") { this.is_weak = val[key]; } } } } } // 流星类 class Commet { x = 0; // 流星 x 坐标 y = 0; // 流星 y 坐标 radius = 0; // 流星半径 opacity = 0; // 流星透明度 tail_length = 0; // 流星尾巴长度 tail_direct = 0; // 流星的方向,暂时未做开发 ori_speed = 0; // 流星的初始速度 velocity = 0; // 流星的加速度,一般来说是个负数,使速度递减 constructor(width, height) { this.init(width, height); } // 初始化流星参数 init(w, h) { this.x = Math.random() * w; this.y = Math.random() * h * 0.8; this.radius = Math.random() * 0.5 + 0.5; this.opacity = Math.random() * 0.7 + 0.4; this.tail_length = Math.random() * 15 + 25; this.ori_speed = Math.random() * 0.5 + 2; this.velocity = -(Math.random() * 0.005 + 0.005); } // 更改参数 setCommetVal(val) { if (!!val) { for (let key in val) { if (key == "x") { this.x = val[key]; } if (key == "y") { this.y = val[key]; } if (key == "radius") { this.radius = val[key]; } if (key == "opacity") { this.opacity = val[key]; } if (key == "tail_length") { this.tail_length = val[key]; } if (key == "tail_direct") { this.tail_direct = val[key]; } if (key == "ori_speed") { this.ori_speed = val[key]; } } } } // 获取参数 get getCommetVal() { return { x: this.x, y: this.y, radius: this.radius, opacity: this.opacity, tail_length: this.tail_length, ori_speed: this.ori_speed, velocity: this.velocity, }; } } // 绘制整个画布的类 class DrawSky { constructor() { this.width; // 画布宽度 this.height; // 画布高度 // 使用双缓冲绘图技术,增强绘制过程的流畅度 // 这是页面真实渲染画布 this.realCanvas = document.createElement("canvas"); document.body.appendChild(this.realCanvas); this.realCtx = this.realCanvas.getContext("2d"); // 这是缓冲绘制画布 this.canvas = document.createElement("canvas"); this.ctx = this.canvas.getContext("2d"); this.moon_radius; // 月亮半径 this.star_arr = []; // 存放星星数组 this.commet_arr = []; // 存放流行数组 this.mountain_arr = []; // 存放山的数组 this.timer = null; this.init(); // 调用初始化方法 // 添加窗口大小改变监听事件 window.addEventListener("resize", () => { if (timer) { window.cancelAnimationFrame(timer); timer = null; } this.cleanCanvas(); this.init(); }); } // 初始化方法画布数据 init() { this.width = window.innerWidth ? window.innerWidth : document.body.clientWidth; this.height = window.innerHeight ? window.innerHeight : document.body.clientHeight; this.moon_radius = 50; this.canvas.width = this.width; this.canvas.height = this.height; this.realCanvas.width = this.width; this.realCanvas.height = this.height; // 执行绘画控制方法 this.drawControl(); } // 第一次开始绘制动画 drawControl() { this.drawSkyBackground(); this.drawMoon(); this.drawStar(); this.drawCommet(); this.drawMountain(); // 实现双缓冲 this.realCtx.drawImage(this.canvas, 0, 0, this.width, this.height); this.cleanCanvas(); this.startAnimate(); } // 循环绘制动画 startAnimate() { // 这是第一种通过 setInterval 控制绘画方法 // if (this.interval) { // clearInterval(this.interval) // } // this.interval = setInterval(() => { // this.cleanCanvas() // this.drawSkyBackground() // this.drawMoon() // this.drawStar() // this.drawCommet() // this.drawMountain() // }, 20) // 这是第二种通过 requestAnimationFrame 控制绘画方法 this.drawSkyBackground(); this.drawMoon(); this.drawStar(); this.drawCommet(); this.drawMountain(); // 将备用画布画好的图片,绘制到页面真正渲染的画布上 this.realCtx.drawImage(this.canvas, 0, 0, this.width, this.height); this.cleanCanvas(); this.timer = window.requestAnimationFrame(() => this.startAnimate()); } // 绘制背景 drawSkyBackground() { // 这种是从上到下的渐变背景 // let gradientColor = this.ctx.createLinearGradient(0, 0, 0, this.height); // gradientColor.addColorStop(0, "#000211"); // gradientColor.addColorStop(0.3, "#080d23"); // gradientColor.addColorStop(0.7, "#18203d"); // gradientColor.addColorStop(1, "#293756"); // this.ctx.fillStyle = gradientColor; // this.ctx.fillRect(0, 0, this.width, this.height); // 这种是中间向四周发散光芒的背景 let radialColor = this.ctx.createRadialGradient( this.width / 2, this.height * 1.5, this.width / 8, this.width / 2, this.height * 0.9, this.width * 2 ); radialColor.addColorStop(0, "#293756"); radialColor.addColorStop(0.5, "rgba(0, 0, 0, 0)"); this.ctx.fillStyle = radialColor; this.ctx.fillRect(0, 0, this.width, this.height); } // 绘制月亮 drawMoon() { let moonRadial = this.ctx.createRadialGradient( this.width / 9 + this.moon_radius, this.width / 9 + this.moon_radius, this.moon_radius * 0.5, this.width / 9 + this.moon_radius, this.width / 9 + this.moon_radius, this.moon_radius ); moonRadial.addColorStop(0, "rgba(255, 255, 255, 1)"); moonRadial.addColorStop(0.6, "rgba(255, 255, 255, 1)"); moonRadial.addColorStop(1, "rgba(255, 255, 255, 0)"); this.ctx.fillStyle = moonRadial; this.ctx.fillRect( this.width / 9, this.width / 9, this.moon_radius * 2, this.moon_radius * 2 ); } // 实例化山的参数 drawMountain() { // 初始化山的数据 if (!this.mountain_arr || this.mountain_arr.length === 0) { let mountain_obj = {}; // 定义起始点坐标 // x 的范围为 [0, this.width], x 方向每次递增的值范围为 [100, 200) // y 的范围为 [50, 70) let start_x = 0; let start_y = this.height - (Math.random() * 20 + 60); // 记录一下最原始的坐标 let ori_x = start_x; let ori_y = start_y; mountain_obj.x = start_x; mountain_obj.y = start_y; this.mountain_arr.push(mountain_obj); while (start_x < this.width) { mountain_obj = {}; // 生成下一个点的坐标 let end_x = Math.random() * 20 + 20 + start_x; let end_y = this.height - (Math.random() * 20 + 60); if (end_x >= this.width) { end_x = this.width; } // 决定本次绘画用直线还是二次贝塞尔曲线 // 0 直线 // 1 二次贝塞尔 let draw_mode = Math.random() >= 0.5 ? 0 : 1; let control_x = 0; let control_y = 0; if (draw_mode === 1) { // 生成控制点坐标 // x 轴控制点在 start_x 和 end_x 之间 // y 轴控制点在 [50, 100) control_x = Math.random() * (end_x - start_x) + start_x; control_y = Math.random() >= 0.5 ? Math.min(end_y, start_y) - Math.random() * 20 : Math.max(end_y, start_y) + Math.random() * 50; } start_x = end_x; start_y = end_y; mountain_obj.draw_mode = draw_mode; mountain_obj.x = end_x; mountain_obj.y = end_y; mountain_obj.control_x = control_x; mountain_obj.control_y = control_y; this.mountain_arr.push(mountain_obj); } } this.drawMountainPic(this.mountain_arr); } // 根据山的数据进行绘制山 drawMountainPic(mountain_arr) { this.ctx.beginPath(); this.ctx.lineTo(mountain_arr[0].x, mountain_arr[0].y); for (let i = 1; i < mountain_arr.length; i++) { if (mountain_arr[i].draw_mode === 0) { this.ctx.lineTo(mountain_arr[i].x, mountain_arr[i].y); } else { this.ctx.quadraticCurveTo( mountain_arr[i].control_x, mountain_arr[i].control_y, mountain_arr[i].x, mountain_arr[i].y ); } } this.ctx.lineTo(this.width, this.height); this.ctx.lineTo(0, this.height); this.ctx.lineTo(mountain_arr[0].x, mountain_arr[0].y); this.ctx.fillStyle = "#000"; this.ctx.fill(); this.ctx.closePath(); } // 实例化流星参数 drawCommet() { // 第一次绘制流星 if (!this.commet_arr || this.commet_arr.length === 0) { let commetNum = Math.random() * 10 + 5; this.commet_arr = []; for (let i = 0; i < commetNum; i++) { // 创建流星实例对象 let commet = new Commet(this.width, this.height); let commet_obj = commet.getCommetVal; this.commet_arr.push(commet); // 绘制流星 this.drawCommetPic(commet_obj); } } // 更改流星位置,实现流星动画 else { for (let i = 0; i < this.commet_arr.length; i++) { let commet_obj = this.commet_arr[i].getCommetVal; commet_obj.ori_speed = commet_obj.ori_speed + commet_obj.velocity > 1 ? commet_obj.ori_speed + commet_obj.velocity : 1; commet_obj.x -= commet_obj.ori_speed / Math.sqrt(2); commet_obj.y += commet_obj.ori_speed / Math.sqrt(2); commet_obj.opacity = commet_obj.opacity - 0.01 > 0 ? commet_obj.opacity - 0.01 : 0; if (commet_obj.opacity === 0 || commet_obj.speed <= 0) { // 销毁当前流星对象,并新建一个 commet_obj = null; this.commet_arr[i] = null; this.commet_arr[i] = new Commet(this.width, this.height); commet_obj = this.commet_arr[i].getCommetVal; } // 绘制流星 this.drawCommetPic(commet_obj); this.commet_arr[i].setCommetVal(commet_obj); } } } // 根据流星的数据进行绘制流星 drawCommetPic(commet_obj) { // 画圆形主体 this.ctx.beginPath(); this.ctx.fillStyle = `rgba(255, 255, 255, ${commet_obj.opacity})`; this.ctx.arc( commet_obj.x, commet_obj.y, commet_obj.radius, 0, 2 * Math.PI ); this.ctx.fill(); this.ctx.closePath(); // 画尾巴 this.ctx.beginPath(); let tailColor = this.ctx.createLinearGradient( commet_obj.x, commet_obj.y, commet_obj.x + Math.sin((45 * Math.PI) / 180) * commet_obj.tail_length, commet_obj.y - Math.sin((45 * Math.PI) / 180) * commet_obj.tail_length ); tailColor.addColorStop(0, `rgba(255, 255, 255, ${commet_obj.opacity})`); tailColor.addColorStop(1, "rgba(255, 255, 255, 0)"); this.ctx.fillStyle = tailColor; this.ctx.strokeStyle = tailColor; this.ctx.lineWidth = commet_obj.radius * 2; this.ctx.moveTo(commet_obj.x, commet_obj.y); this.ctx.lineTo( commet_obj.x + Math.sin((45 * Math.PI) / 180) * commet_obj.tail_length, commet_obj.y - Math.sin((45 * Math.PI) / 180) * commet_obj.tail_length ); this.ctx.fill(); this.ctx.stroke(); this.ctx.closePath(); } // 实例化星星参数 drawStar() { // 初始化星星数组 if (!this.star_arr || this.star_arr.length === 0) { let star_num = Math.random() * 100 + 50; this.star_arr = []; for (let i = 0; i < star_num; i++) { let star = new Star(this.width, this.height, this.moon_radius); let star_obj = star.getStarVal; this.star_arr.push(star); this.drawStarPic(star_obj); } } // 更改星星透明度,实现星星渐隐动画 // 根据窗口中心点,计算星星旋转坐标,实现星移 else { for (let i = 0; i < this.star_arr.length; i++) { let star_obj = this.star_arr[i].getStarVal; if (star_obj.is_weak) { // 降低透明度 star_obj.opacity = star_obj.opacity - 0.01 > 0 ? star_obj.opacity - 0.01 : 0; if (star_obj.opacity <= 0) { star_obj.is_weak = false; } } else { // 提高透明度 star_obj.opacity = star_obj.opacity + 0.01 < 1 ? star_obj.opacity + 0.01 : 1; if (star_obj.opacity >= 1) { star_obj.is_weak = true; } } // 转换原点坐标为左下角,得到新的星星坐标点以及中心点 let star_x = star_obj.x, star_y = this.height - star_obj.y, c_x = this.width / 2, c_y = this.height / 2; // 计算当前星星坐标和中心点的距离 let r = Math.sqrt( Math.pow(star_x - c_x, 2) + Math.pow(star_y - c_y, 2) ); // 计算当前星星坐标相对中心点的角度 let angle = (Math.atan2(star_y - c_y, star_x - c_x) * 180) / Math.PI; angle = angle + 0.1 <= 360 ? angle + 0.1 : 0; let x = c_x + Math.sin((angle * Math.PI) / 180) * r; let y = c_y - Math.cos((angle * Math.PI) / 180) * r; // 将新的星星坐标转换为原来的坐标系坐标 star_obj.x = x; star_obj.y = this.height - y; this.star_arr[i].setStarVal(star_obj); this.drawStarPic(star_obj); } } } // 根据星星的数据进行绘制星星 drawStarPic(star_obj) { this.ctx.beginPath(); this.ctx.fillStyle = `rgba(255, 255, 255, ${star_obj.opacity})`; this.ctx.arc(star_obj.x, star_obj.y, star_obj.radius, 0, 2 * Math.PI); this.ctx.fill(); this.ctx.closePath(); } // 清空画布 cleanCanvas() { this.ctx.clearRect(0, 0, this.width, this.height); } // 暂停绘画函数,可用于观察绘制过程 sleep() { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); }, 1000); }); } } // 新建绘制类的实例对象,开始绘制 new DrawSky(); </script> </html>
效果预览地址
代码中还存在星星绘制过程画面闪烁的问题,暂未找到原因,欢迎大家批评指正啦~ -
openGL绘制正方体分别实现简单颜色绘制、纹理绘制、光照绘制
2016-12-17 13:26:44使用openGL绘制正方体; 面1:使用简单颜色绘制,颜色为绿色; 面2:使用简单颜色绘制,颜色为渐变色; 面3:绘制一维纹理; 面4:绘制二维纹理; 面5:光照绘制,黄色; 面6:光照绘制,橘色; 绘制效果如下: ...使用openGL绘制正方体;
面1:使用简单颜色绘制,颜色为绿色;
面2:使用简单颜色绘制,颜色为渐变色;
面3:绘制一维纹理;
面4:绘制二维纹理;
面5:光照绘制,黄色;
面6:光照绘制,橘色;
绘制效果如下:
需要注意的问题:
1、 在绘制纹理和光照的时候,要正确设置每个面的法线方向;使用函数glNormal3f( )进行设置;
2、 使用光照的时候,如果只是局部光照,要在局部光照结束之后,关闭光源,否则别的面也被光照;使用函数glDisable(GL_LIGHTING)实现;
3、 使用png图片作为二维纹理的时候需要将原始图片进行上下翻转,因为OpenGL以左下角为图像原点;自定义函数void upsidedown32(unsigned char *pImage, unsigned width, unsignedheight)实现图像上下翻转;
#include <GL/glut.h> #include "lodepng.h" void init(void); void reshape(int w, int h); void mouse(int button, int state, int x, int y); void motion(int x, int y); void display(void); void drawCoordinates(void); void drawTetrahedron(void); int mx,my; //position of mouse int m_state=0; //mouse usage float x_angle=20.0f, y_angle=20.0f; //angle of eye float dist=10.0f; //distance from the eye GLuint texDog, tex1D; void upsidedown32(unsigned char *pImage, unsigned width, unsigned height) //Upside down the image { unsigned i; unsigned char *pLine; pLine = (unsigned char *)malloc(4*width); if(pLine == NULL) { printf("No memory left!"); exit(0); } for(i=0; i<height/2; i++) { memcpy(pLine, &pImage[i*4*width], 4*width); memcpy(&pImage[i*4*width], &pImage[(height-1-i)*4*width], 4*width); memcpy(&pImage[(height-1-i)*4*width], pLine, 4*width); } free(pLine); } void init(void) { int i; unsigned error; unsigned width, height; unsigned char *pDogImg; unsigned char img1D[16][3]; error = lodepng_decode32_file(&pDogImg, &width, &height, "dog.png"); if(error) { printf("error %u: %s\n", error, lodepng_error_text(error)); exit(0); } upsidedown32(pDogImg, width, height); //Upside down the image glGenTextures(1, &texDog); //生成纹理号 glBindTexture(GL_TEXTURE_2D, texDog); //纹理绑定 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pDogImg); //定义纹理数据 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //设置纹理目标参数 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); free(pDogImg); for(i=0; i<16; i++) //构造一维纹理 if(i%4) img1D[i][0] = img1D[i][1] = img1D[i][2] = 255; else img1D[i][0] = img1D[i][1] = img1D[i][2] = 0; glGenTextures(1, &tex1D); glBindTexture(GL_TEXTURE_1D, tex1D); glTexImage1D(GL_TEXTURE_1D, 0, 3, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, img1D); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //设置纹理环境参数 glEnable(GL_DEPTH_TEST); } void reshape(int w, int h) { glViewport(0, 0, w, h); } void mouse(int button, int state, int x, int y) { if(button==GLUT_LEFT_BUTTON && state == GLUT_DOWN) { mx = x; my = y; m_state = 0; } if(button==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { mx = x; my = y; m_state = 1; } } void motion(int x, int y) { int dx,dy; //offset of mouse; dx = x-mx; dy = y-my; if(m_state == 0) { y_angle += dx*0.1f; x_angle += dy*0.1f; } else if(m_state == 1) dist += (dx+dy)*0.05f; mx = x; my = y; glutPostRedisplay(); } void display(void) { int rect[4]; float w, h; //float lit_position[] = {0.0f, 0.0f, 1.0f, 0.0f}; //float mat_yellow[] = {1.0f, 1.0f, 0.0f, 1.0f}; glGetIntegerv(GL_VIEWPORT, rect); w = rect[2]; h = rect[3]; glClearColor(1.0f,1.0f,1.0f,0.0f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //对应单位阵I if(h < 1) h=1; gluPerspective(30.0, w/h, 0.1, 20.0); //对应变换阵T0 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //对应单位阵I glTranslated(0.0, 0.0, -dist); //对应变换阵T1 glRotatef(x_angle, 1.0f, 0.0f, 0.0f); //对应变换阵T2 glRotatef(y_angle, 0.0f, 1.0f, 0.0f); //对应变换阵T3 glPushMatrix(); glScalef(1.5f, 1.5f, 1.5f); //对应变换阵T6 drawCoordinates(); drawTetrahedron(); glPopMatrix(); glFlush(); glutSwapBuffers(); } void drawTetrahedron(void) { float pnt[8][3] = {{0.0,0.0,0.0}, {0.0,1.0,0.0}, {1.0,1.0,0.0}, {1.0,0.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0},{1.0,1.0,1.0},{1.0,0.0,1.0}}; int tetra[6][4] = {{0,1,2,3}, {1,5,6,2}, {0,3,7,4}, {2,6,7,3},{0,4,5,1},{4,7,6,5}}; float lit_position1[] = {1.0f, 0.0f, 0.0f, 0.0f}; float lit_position2[] = {-1.0f, 0.0f, 0.0f, 0.0f}; float yellow[] = {1.0f, 1.0f, 0.0f, 1.0f}; float orange[] = {1.0f, 0.5f, 0.0f, 1.0f}; //glNormal3f(0.0f, 0.0f, -1.0f); glBegin(GL_QUADS); //简单颜色绘两个面,一个单一色,一个渐变色 glColor3f(0.0f,1.0f,0.0f); //绿色 glVertex3fv(pnt[tetra[0][0]]); //glVertex3fv(pnt[0]); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3fv(pnt[tetra[0][1]]); //glVertex3fv(pnt[2]); glVertex3f(0.0f, 1.0f, 0.0f); glVertex3fv(pnt[tetra[0][2]]); //glVertex3fv(pnt[1]); glVertex3f(1.0f, 0.0f, 0.0f); glVertex3fv(pnt[tetra[0][3]]); glEnd(); //glNormal3f(0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); glColor3f(0.0f,1.0f,1.0f); glVertex3fv(pnt[tetra[1][0]]); glColor3f(1.0f,0.0f,1.0f); glVertex3fv(pnt[tetra[1][1]]); glColor3f(1.0f,1.0f,0.0f); glVertex3fv(pnt[tetra[1][2]]); glColor3f(1.0f,1.0f,1.0f); glVertex3fv(pnt[tetra[1][3]]); glEnd(); /* 绘制纹理图案 */ glNormal3f(0.0f, -1.0f, 0.0f);//一维纹理绘制 glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_1D); glBegin(GL_POLYGON); glTexCoord1f(0.0f); glVertex3fv(pnt[tetra[2][0]]); //设置纹理坐标 glTexCoord1f(0.0f); glVertex3fv(pnt[tetra[2][1]]); glTexCoord1f(1.0f); glVertex3fv(pnt[tetra[2][2]]); glTexCoord1f(1.0f); glVertex3fv(pnt[tetra[2][3]]); glEnd(); glNormal3f(0.0f, 0.0f, 1.0f); //二维纹理的绘制 glDisable(GL_TEXTURE_1D); glEnable(GL_TEXTURE_2D); glBegin(GL_POLYGON); // 正对面 glTexCoord2f(0.0f, 0.0f); glVertex3fv(pnt[tetra[5][0]]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(pnt[tetra[5][1]]); glTexCoord2f(1.0f, 1.0f); glVertex3fv(pnt[tetra[5][2]]); glTexCoord2f(0.0f, 1.0f); glVertex3fv(pnt[tetra[5][3]]); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_1D); /* 两个光照面 */ glLightfv(GL_LIGHT0, GL_POSITION, lit_position2); //光源位置 glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); //之后使用光照模型计算顶点颜色 glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow); glNormal3f(-1.0f,0.0f,0.0f); glBegin(GL_QUADS); glVertex3fv(pnt[tetra[4][0]]); glVertex3fv(pnt[tetra[4][1]]); glVertex3fv(pnt[tetra[4][2]]); glVertex3fv(pnt[tetra[4][3]]); glEnd(); glDisable(GL_LIGHTING); //(不能省略)之后顶点颜色为当前颜色,当前颜色可以通过glColor*函数指定。 glLightfv(GL_LIGHT0, GL_POSITION, lit_position1); //普通光照(橘色) glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT, GL_DIFFUSE, orange); glNormal3f(1.0f,0.0f,0.0f); glBegin(GL_QUADS); glVertex3fv(pnt[tetra[3][0]]); glVertex3fv(pnt[tetra[3][1]]); glVertex3fv(pnt[tetra[3][2]]); glVertex3fv(pnt[tetra[3][3]]); glEnd(); glDisable(GL_LIGHTING); } void drawCoordinates(void) { glColor3f(1.0f,0.0f,0.0f); //画红色的x轴 glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(2.0f, 0.0f, 0.0f); glEnd(); glColor3f(0.0,1.0,0.0); //画绿色的y轴 glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 2.0f, 0.0f); glEnd(); glColor3f(0.0,0.0,1.0); //画蓝色的z轴 glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 2.0f); glEnd(); } int main(int argc,char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("model & zbuffer"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); glDeleteTextures(1, &texDog); //删除纹理 glDeleteTextures(1, &tex1D); //删除纹理 return 0; }
-
Android视图绘制流程完全解析,带你一步步深入了解View(二)
2013-12-26 08:30:56那么本篇文章中,我们将继续对View进行深入探究,看一看它的绘制流程到底是什么样的。如果你还没有看过我的上一篇文章,可以先去阅读 Android LayoutInflater原理分析,带你一步步深入了解View(一) 。 相信每个... -
Java绘图: 使用 Graphics 类绘制线段、矩形、椭圆/圆弧/扇形、图片、文本
2017-02-19 15:10:26Graphics 类相当于一个画布,每个 Swing 组件都通过 Graphics 对象来绘制显示。绘图的原点位于组件的左上角,如下图所示: Graphics类中常用的绘制相关方法: ○ 参数 / 设置: // 创建... -
C# 绘制实时曲线包括绘制坐标轴
2014-08-06 02:08:35C# 绘制实时曲线及坐标轴,实现实时的图像处理操作。 -
D3 二维图表的绘制系列(一)介绍
2019-08-02 11:45:201 介绍 D3 (或者叫 D3.js )是一个基于 web 标准的 JavaScript 可视化库.... D3 结合了强大的可视化交互技术以及数据驱动 ...学习了d3一个多月,通过绘制一些简单的二维图表,总算入门了d3。强烈推荐《D3数据可视化实战... -
Open3D绘制3D坐标,绘制点云
2019-10-10 10:18:02Open3D绘制3D坐标,绘制点云 # -*-coding: utf-8 -*- """ @Project: PyKinect2-OpenCV @File : open3d_test.py @Author : panjq @E-mail : pan_jinquan@163.com @Date : 2019-10-10 09:49:27 ""... -
drawRect的绘制的使用(绘制文本字符、绘制图片、绘制图形)
2017-02-27 16:08:19通过重写UIView的drawRect方法进行绘制使用,如绘制文本字符、绘制图片、绘制图形等。 注意事项: 1、设置frame的属性,或调用setNeedsDisplay时才会调用drawRect方法。 2、在绘制过程中 (1)针对实际情况获取图形... -
Cadence 焊盘绘制
2020-11-28 15:26:55概述 首先,Cadence不会像AD那样,画PCB封装与焊盘可以在同一个窗口完成,Cadence画...当然也可以使用 “OrCAD Library Builder” 绘制封装神器来完成。 一、新建工程 1、在系统开始,找到Cadence PCB Utilities... -
iOS UI绘制原理
2020-04-14 08:46:01一、UIView的绘制流程 UIView绘制流程 下面我们来对这个流程进行说明: 当我们调用[UIView setNeedsDisplay]方法时,并没有执行立即执行绘制工作。 调用setNeedDisplay之后,系统会调用view对应layer的... -
Cadence 绘制板边框Outline与绘制禁止布线区(Route Keepout)
2020-12-11 09:25:11概述 本人使用Cadence 17.4版本,在这做下笔录,绘制板边与限制布线区域方法。 一、绘制板边 二、设置布线区域 -
体绘制之体绘制管线
2017-04-04 16:28:02体绘制体绘制,又称作三维重建,是一种直接利用体数据来生成二维图像的绘制技术。与面绘制不同,体绘制技术不需要提取体数据内部的等值面,它是一个对三维体数据进行采样和合成的过程。示例说明CMakeLists.txt文件... -
iOS异步绘制原理
2020-04-21 16:37:29具体过程是系统会把 UIView 显示的内容(包括 UILabel 的文字,UIImageView 的图片等)绘制在一张画布上,完成后倒出图片赋值给 CALayer 的 contents 属性,完成显示。 这其中的工作都是在主线程中完成的,这就导致... -
Qt基本图形绘制(圆、圆角矩形、圆弧、椭圆、扇形等)
2018-03-22 10:45:47绘制矩形 核心代码: paint->drawRect(20,20,160,160); 第1、2个参数制定矩形的左上角起点,第3个参数制定矩形的长度,第4个参数指定矩形的宽度 绘制圆和椭圆 核心代码: paint->set... -
Javafx 时钟绘制
2020-11-12 13:57:28第一个为 public void dials,绘制表盘 第二个为public void scale,绘制刻度,这里需要注意的是字体旋转 第三个为public void point,绘制秒分时针以及打印时间,需要注意的是进制问题 总的javafx源码如下: ... -
python绘制蟒蛇,绘制五彩蟒蛇
2019-05-06 23:25:59python绘制蟒蛇,绘制五彩蟒蛇 1.用Python绘制蟒蛇 from turtle import * setup(650,350,200,200) penup() fd(-250) pendown() pensize(25) pencolor("purple") seth(-40) for i in range(4): circle(40,80) ... -
iOS 图形绘制
2017-06-23 12:47:43在许多需要图形显示数据的应用中常常需要进行图形绘制,例如股票金融。在一些特定动画中,我们同样需要结合图形的绘制。 - 重写 drawrect - 外部代理 - CAShapeLayer -
在线绘制函数图像和在线图标绘制网址
2019-02-15 16:33:35经过寻找,找到了几个在线绘制函数图像的网址,可以不用matlab和geogebra软件绘制了。 数学函数图像: 第一个:Desmos 首推 第二个:fooplot 可以绘制分段函数比如: (x>=1)x*3/(3*x+1) (x<1... -
matplotlib绘制直方图、条形图和饼图
2018-01-18 22:02:33matplotlib绘制直方图、条形图和饼图 matplotlib是一个非常强大的Python第三方绘图包,可以绘制非常多非常漂亮的图形。matplotlib.pyplot提供了一个类Matlab的函数式编程环境。通常的绘图任务,都可以通过... -
使用matlab绘制世界地图并根据经纬度绘制点位(附m_map的下载与安装说明)
2019-03-26 17:07:56使用matlab绘制世界地图有两种方法(自己使用过的,可能有别的我不了解的方法):第一种是worldmap和geoshow;第二种是利用m_map工具箱;下面分别介绍这两种方法。 1.worldmap & geoshow worldmap和geoshow是... -
使用matplotlib绘制折线图,柱状图,柱线混合图
2019-08-31 21:54:49matplotlib介绍 Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 ...matplotlib绘制折线图 绘制一条折线的折线图 # -*- c... -
MATLAB05:绘制高级图表
2019-11-16 16:22:30文章目录MATLAB05:绘制高级图表二维图表折线图对数坐标系图线双y轴图线极坐标图线统计图表三维图表 MATLAB05:绘制高级图表 二维图表 折线图 函数 图形描述 loglog() x轴和y轴都取对数坐标 semilogx() x轴... -
Python使用Plotly绘图工具,绘制甘特图
2019-03-27 18:38:56今天来讲一下如何使用Python 的绘图工具Plotly来绘制甘特图的方法 甘特图大家应该了解熟悉,就是通过条形来显示项目的进度、时间安排等相关情况的。 我们今天来学习一下,如何使用ployly来绘制甘特图 绘制甘特图... -
-
Matlab绘制折线图详细方法
2018-04-11 12:17:55Matlab绘制折线图属于非常基本的功能,首先给出一个示例代码,有详细的解释,可以根据自己需求进行修改。 x=1:1:5;%x轴上的数据,第一个值代表数据开始,第二个值代表间隔,第三个值代表终止 a=[203.024,113.857... -
什么是过度绘制,如何防止过度绘制
2019-02-18 20:52:08过度绘制是指,屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结 构里,如果不可见的UI也在做绘制的操作,会导致某些像素区域被绘制了多次,同时 会浪费CPU和GPU资源。 在Android手机设置的... -
Flutter 绘制Paint
2019-08-31 10:40:17Flutter 的绘制主要涉及两个Widget: CustomPainter, CustomPaint CustomPainter:提供画布的组件; 有几个主要的参数: a. painter : 绘制的对象,是一个CustomPaint。它的绘制是在children之前。如果设置了...
-
apache-jmeter-2.9.7z
-
ATTO--U盘移动硬盘速度测试工具(attodiskbenchmarks-v2.47).rar
-
osg学习历程(2)—Win7下编译基于VS2013 X64的geos3.5.2
-
395——至少有K个重复字符的最长子串
-
工程制图 AutoCAD 2012 从二维到三维
-
基于Qt的LibVLC开发教程
-
使用 Linux 平台充当 Router 路由器
-
U盘量产软件.zip
-
PowerBI重要外部工具详解
-
读写锁
-
[全案]非付费推广之QQ群推广方案(2011年4月1日更新).pdf
-
SQL手工注入语句
-
MySQL NDB Cluster 负载均衡和高可用集群
-
2010-2011年品牌微博营销执行方案.ppt
-
产品经理的情报收集与分析.pdf
-
LVS + Keepalived 实现 MySQL 负载均衡与高可用
-
awk命令详解
-
jn82901336.github.io-源码
-
华为1+X认证——网络系统建设与运维(初级)
-
FPGA入门学习路线.pdf