目录

前言

一、x,y轴绘制

1.代码展示

2.代码讲解

2.1 绘制坐标轴

2.2标箭头

2.3 写x,y轴标签

二、轴刻度绘制

1.代码展示

2.代码讲解

1.绘制轴刻度并标值

2.isdiv()函数

三、主程序和图像绘制

1.代码展示

2.代码讲解

1.绘制方法

2.函数解析式

3.检测环节

4.主程序

总结


前言

如今数学界中很多分析方法都被科学界广泛使用,比如图像和解析式。他们用于数学本身,比如研究发展微积分,线性代数,非欧几何,以及统计学等,而这些数学领域的知识又广泛应用于自然科学的各类研究。从图像到解析式本身是一项壮举,因为他把几何与代数联系了起来。这让研究自然科学更容易了,因为你无法在摆钟上看到一个他高度和动能的关系式,但是你可以通过随着时间变化,摆钟的高度变化作一个图像,再同理做一个动能的变化图像,通过图像研究他的代数解析式和图像关系,然后再用数学的法则运算得到最终结果后,总结出规律。

但现在的问题是,大多图像都是一条或几条平滑的曲线,不是我们能用一把尺子就能画的出来的直线。这个时候,我们就需要计算机的帮助,我们希望我们输入一个解析式,他就能返回对应的图像,或者...没有图像。好,我们现在开始了解他是怎么实现图像绘制的吧


一、x,y轴绘制

1.代码展示

#画坐标轴,标箭头,写坐标点
import turtle
def draw_line(x,y,heading,length,color):#画坐标轴turtle.pensize(4)turtle.shape("circle")turtle.up()turtle.goto(x,y)turtle.setheading(heading)turtle.down()turtle.pencolor(color)turtle.fd(length)#标x,y轴箭头turtle.left(135)turtle.fd(15)turtle.back(15)turtle.setheading(heading)turtle.right(135)turtle.fd(15)turtle.back(15)#坐标轴信息turtle.setheading(heading)turtle.up()turtle.fd(20)turtle.down()if heading==0:turtle.write("x",font=("arial",24,"bold"))if heading==90:turtle.write("y", font=("arial", 24, "bold"))

2.代码讲解

这段画x,y轴的代码要分三部分。1.画x,y坐标轴  2.给轴标上箭头表示正x和正y的方向  3.写坐标轴信息---给坐标轴写上x,y的标签

2.1 绘制坐标轴

画坐标轴说白了就是画两条互相垂直的线段,就是美化线段的代码比较多。我们先设置线段粗细,设置海龟画笔形状,然后抬笔并落到开始绘制的位置,然后turtle.setheading()设置绘制初始角度(默认0°是海龟画笔朝右,水平于屏幕。比如,如果是画y轴,就设置turtle.setheading(90))。接下来选择绘制线段的颜色,落笔,然后画笔就向前走一段距离,抬笔。这样我们就完成了一个轴的绘制。

2.2标箭头

在原来位置的基础上向左旋转135°,向前画十五格,再退回到原来位置和绘制前角度,然后向右边旋转相同度数,向前,向后,哎,完成箭头绘制!

2.3 写x,y轴标签

首先写之前方向要清楚!然后才到抬笔,海龟画笔按方向移动20格距离,然后落笔开始写信息。如果heading==0,即此时绘制的是x轴,就写上x,第二个参数负责字体样式(这里是"arial")字体大小(这里大小为24),和其他装饰(这里选了"bold"即加粗字体)。y轴类似


二、轴刻度绘制

1.代码展示

import turtle
import osclass Scale:@classmethoddef mark(cls, list_num, heading, convert):  # list_num存储了坐标轴的所有刻度值turtle.pensize(1)turtle.setheading(heading)turtle.up()for i in list_num:if heading == 90:  # x轴刻度垂直于屏幕turtle.goto(i, 0)turtle.color("black")elif heading == 0:turtle.goto(0, i)  # i 代表高度turtle.color("blue")turtle.down()turtle.fd(15)  # 轴刻度长15格turtle.up()turtle.back(30)  # 后退30格来标注刻度值turtle.write(cls.isdiv(i, convert), align="center", font=("arial", 6))turtle.up()turtle.home()  # 回到起始位置准备下一步的绘制@classmethoddef isdiv(cls, value, cvt):  # value参数表示的是当前刻度值if value%cvt!=0:return round(value/cvt, 1)  # 若不整除则保留一位小数else:return int(value/cvt)

2.代码讲解

这段代码主要分两个部分,第一个是绘制轴刻度和轴刻度值,一个是判断生成的轴刻度值列表中的所有数是否整除转换。那什么是转换呢?因为海龟画函数图像的原理是:根据解析式,得到一定范围内整数x和y值,每个整数x和其对应的y组成一个点。每个整数非常小,所以一个正常大小的图像需要的刻度值就很大。为了让轴刻度值尽可能地按照数学界的大小走,我们将实际刻度值除以一个数让他变小一些。

1.绘制轴刻度并标值

在类的mark()函数中第一行设置画笔大小为一,然后就是设置绘制方向,如果是画x轴的坐标轴刻度那画的方向就是90°,垂直于屏幕,y轴的相反。接下来就是一个循环。list_num是什么东西?他在主程序中会有详细信息。他大概记载了轴刻度要画的位置。抬笔之后就是一个判断,通过判断setheading()内的heading参数确定要去的位置,从而使其能够在正确的位置画出相应的x,y坐标刻度。接下来落笔,按heading方向向前画15个单位,并在画笔退三十个单位长度后使用write()函数写坐标刻度值。

2.isdiv()方法

想完全理解这一段要先阅读下面主程序的“检测环节”内容,我现在做一个简单的介绍,为什么需要isdiv()方法。我们一般会在画刻度后标上相应的刻度值,这样便于我们涉足非欧几何领域。但是如果这个刻度值是以海龟库的单位长度为基准的话,每个刻度值将会很大。而这并不是我们想看到的,原因是这样不便于我们观察研究函数图像,也不方便我们后续用代数方法去计算得到该函数的其他性质。所以我们需要一个参数cvt,用他来除这个刻度值,让其变小一点。

考虑到还有除不尽的问题,我又在isdiv()方法中设立了if ...else条件判断语句。如果不取余不为零,就保留商的一位小数,整除则另起一行直接返回商。毕竟18.0,20.0这样的数字并不好看,同理,18.04738,20.89208也丑陋无比。需要注意的是,我们调用isdiv()到另一个类方法mark()中使用的格式是cls.isdiv()而不是isdiv()。这个语法不是无缘无故出现的,他告诉编译器isdiv()是Scale类中的另一个方法,而不是随便从哪里蹦出来的一个函数。


三、主程序和图像绘制

1.代码展示

import turtle, os, math
import xy_axis#导入存放绘制x,y轴的程序的源文件
from mark_label import Scale#导入存放绘制标坐标轴刻度的程序的源文件def draw_func(a,b,func,cvt,color):#参数b,a是分别是函数定义域的上界和下界turtle.speed(0)turtle.pensize(2)turtle.color(color)turtle.penup()for x in range(a,b,5):y=func(x)turtle.goto(x,y)turtle.pendown()if x%100==0:#标记能整除一百的坐标turtle.dot(6,"blue")turtle.up()turtle.goto(x+13,y)turtle.write(f"({int(x/cvt)},{int(y/cvt)})")turtle.goto(x,y)turtle.down()def line(x):y=2*x+100return ydef curve2(x):y=1/20*x*x-1/40*xreturn ydef curve3(x):y=1/2000*x*x*x-1/50*xreturn ydef sin(x):y=math.sin(x*20)*40return ydef curve4(x):y=math.sqrt(x)*10return y#检测正/负轴长能否被间隔长整除,这保证了所有间隔都相等
def isvalid_len(length,interval):if (length/2)%interval==0:return lengthelse:print("invalid length or step value")os._exit(0)#检测比例因子是否为整数
def dec(num):if len(str(num).split("."))>1:return Trueelse:return False#用户输入和检测环节
step = 30
length = 720
cvt1=6
obj=Scale()
R1=isvalid_len(length,step)#R1表示刻度间隔长if cvt1<0 or cvt1>step or dec(cvt1):print("invalid convertion")os._exit(0)
list_num=[-int(R1/2)+i*step for i in range(int(R1/step+1))]#list comprehension
print(list_num)#绘制坐标轴,这里把坐标轴画在了海龟画布正中央。
turtle.setup(900, 900)
xy_axis.draw_line(-int(R1/2), 0, 0, R1, "black")
xy_axis.draw_line(0, -int(R1/2), 90, R1, "blue")#绘制轴刻度
obj.mark(list_num, 0, cvt1)
obj.mark(list_num,90,cvt1)#绘制函数图像
colors=["red","darkblue","orange","lightblue","darkgreen","darkgoldenrod"]
lst=[line,curve2,curve3,sin]
for i in range(len(lst)):  draw_func(-85, 90, lst[i],cvt1, colors[i%len(colors)])
draw_func(0,200,curve4,cvt1,"darkgreen")#该函数图像绘制需要单独列出,因为定义域是[0,∞)turtle.done()

2.代码讲解

这段代码列举了绘制一次,二次和三次函数,三角函数和幂函数的功能。三次函数要注意,因为函数很陡峭,所以我们尽量把x控制在[-90,90]的范围内,不然到时候你等一分钟都等不到他画完。

该代码分几部分,分别是:1.函数从解析式到图像的绘制方法 2.函数解析式 3.检测用户输入的进率和轴长是否符合规范 4.主程序,绘制坐标轴和函数

1.绘制方法

这个绘制方法其实是很简单易懂的,原理和我们上学时学的什么5点法画曲线相像,只是说他会在函数(在程序中是参数func)的定义域中每个整数x上都取一个点,所以画的满精准。注意,这里 if x%100==0 条件语句内的代码块会把x值整除100的点标上,大家可以根据需要,指定程序去标一些特殊点,比如y==0的点(可以用来求高次方程的近似解),或者和其他函数的交点。

2.函数解析式

这里用到了math库,第一个绘制一次函数f(x)=kx+b(k!=0),然后依次是二次f(x)=ax^2+bx+c(a!=0)、三次函数f(x)=ax^3+bx^2+cx+d(a!=0)、正弦函数f(x)=sin(x)和幂函数f(x)=x^α,其中α等于1/2,可以推出定义域为[0,∞)。

另外,这里一定要注意把函数解析式的系数写小一些,因为之前提过,海龟库的单位1比数学中的长度要小很多,所以如果按正常系数大小来标,你得到的将是一个缩小很多倍的函数曲线——这对于做研究很不方便。

3.检测环节

“用户输入”代码块中找到变量length了么?他表示的是x/y坐标轴的长度(注:x,y轴长度相等,且正轴和负轴长度相等)。那么给他除以二就是把轴拆成了两段,一段是负数轴,一段是正数轴。我们目前想要解决的问题是,到底mark()函数要在轴上画多少个刻度。因为轴刻度之间间隔相等,那不难得出,要画的刻度数量=轴总长(length)/刻度间隔长(step)+1。

有了思路,我们看代码。坐标轴上所有刻度的绘制可以用一个循环实现,该循环从负半轴第一个刻度小突起开始,每次循环都给他加上一个间隔,并将该结果储存至刻度坐标列表list_num中。那要进行多少次循环呢?在程序中是循环总次数可以写成:int(R1/step+1)。这里加一是因为总间隔数量总比总刻度数量要少一。你说list_num列表生成式看不懂?没关系,我们把它拆开来看。

list_num=[-int(R1/2)+i*step for i in range(int(R1/step+1))]#等价于以下代码:
startPos=-int(R1/2)#坐标起始位置
number=int(R1/step)
list_num=[]
for i in range(number+1):list_num.append(startPos+i*step)#每一个元素都是坐标刻度的位置

注:我们为了让坐标系处于海龟画布的中心,才把坐标起始位置设成了轴总长的一半的相反数-int(R1/2)。懂了list_num这个记录轴刻度位置的列表,我们审视一下其他环节。

isvalid_len()函数

前面我们提到list_num。大家有没有想过,如果正负半轴长(length/2)无法被刻度间隔长step整除会怎么样(比如length是个奇数)?那么就会出现正负半轴长短不一致的情况。而且因为除不尽,轴刻度的实际间隔并不完全相等。我们想要的是一个好看又对称的坐标轴,所以我们要避免这个情况。isvalid_len()函数华丽登场!他可以检测用户输入的轴长的一半是否能被间隔整除,一旦不能被整除,就打印“无效输入”并用os._exit(0)停止程序。

怪了,那为什么不是轴长,而是他的一半呢?举个例子,间隔大小20,用户输入轴长180。虽然180确实可以被20整除,但是90/20=4.5......每个半轴有4.5个间隔?那这样原点在哪里呢?所以要用半轴长90取余间隔20,如果余数不为零,就表示他无法被整除,就说明length或step的值有问题,反之亦然。

dec()函数

另外还有一个检测cvt1大小的代码块。cvt1是一个调整比例的数,所以他既不能大于间隔,也不能小于0,还不能是小数。判断大小的在dec()函数下面的“用户输入和检测环节”中有写,这里就不再赘述。而判断cvt1是否为小数的函数是dec()。他把整型转为字符串,并调用split()函数,以"."为标识符,将该字符串的小数部分和整数部分分开并存储进列表中,返回该列表。随后我们再用len()判断列表中有两个还是一个元素。两个说明是小数,反之是整数。

4.主程序

接下来就是主程序了,分为三个部分,绘制坐标轴,绘制轴刻度,绘制函数。(可能内容会有与之前重复的部分)

turtle.setup()是设置海龟画布的大小,有他没他都无所谓,全凭个人喜好。draw_line()第一第二个参数是x,y值,他代表轴开始画的具体坐标,反正在负半轴。第三个参数是海龟画笔的起始绘制方向。输入0代表横着画,水平于屏幕;90代表竖着画,垂直于屏幕。绘制轴刻度没什么好说的

绘制函数直线曲线这里使用了个for循环遍历列表lst。lst里面每一个元素都是一个对应关系,这样一来,下次再新添加函数解析式时,只要把他门的自定义函数名写到列表lst中就可以生成它对应的图像了,多方便!当然,像y=x^(1/2)这种x定义域不能为负的函数就要单独拎出来处理,不过除了他这种以外,其他函数都可以在循环中,参数基本都是一样的。颜色用的是老方法:取余循环取出列表colors中的元素当作直线/曲线的颜色。

补充

在这里补充一个有趣的数学现象。我们注意到,如果刻度间隔长step能被cvt整除的话,所有坐标值都能被cvt整除。在初等数论中,我们有:若a|b, b|c 则a|c(a, b, c均为整数)。在列表生成式的分解中我们看到,每一个坐标刻度值都可以用startPos+i*step表示。我们已经用isvalid_len()函数测过,length/2是可以被step整除的,且step整除他自己。根据另外一条定理:若a|b, a|c 则a|bx+cy (x,y均是不为零的整数),因此我们知道step|startPos+i*step,那么cvt|startPos+i*step(cvt为整数,step为整数),证毕。


总结

海龟库只能实现一些基本图像的绘制,且这个绘制方法对于绘制三角函数,指数对数类函数等还是有一定限制的——毕竟我们从他的绘制原理不难看出他的绘制精度还有待提高。他实际上不是专门设计出来绘制图像的库。随着大家学习的深入,会接触到像matplotlib,numpy这种强大的第三方库,使用它绘制各类函数图像会更加的简单快捷,因为他的方法都是包装好了的,你不需要写多少代码他就能帮你生成图像。

不过不论是海龟还是numpy,他们之间绘制图像的底层逻辑都是十分相似的,因此这篇文章足以让你了解部分底层逻辑,拓展知识。

函数图像绘制python海龟库相关推荐

  1. 【Python】函数图像绘制:二维图像、三维图像、散点图、心形图

    [Python]函数图像绘制:二维图像.三维图像.散点图.心形图 所有需要用的包 二维图像 三维图像 散点图绘制 心形图绘制 所有需要用的包 from mpl_toolkits.mplot3d imp ...

  2. 【圣诞专场】—— 用python海龟库实现圣诞装饰(圣诞树,拐杖糖,圣诞火车,圣诞雪人,圣诞祝福)~~c++《铃儿响叮当》

    本文主要介绍了圣诞装饰的python实现,展示出最终效果.实验步骤.及相关知识,在文末附录中,小编还会介绍一些这次活动没有运用到的海龟库知识.用c++编译出圣诞树.用c++编译出<铃儿响叮当&g ...

  3. 在Authorware中实现动态函数图像绘制的程序实现过程

    2019独角兽企业重金招聘Python工程师标准>>> 使用过由Macromadia公司出品的Authorware多媒体制作软件的设计师们,都应该会知道其实他是一款非常强大的功能全面 ...

  4. matlab一般函数的绘制方法,基于MATLAB的函数图像绘制方法

    C DOI:10.16707~.cnki.fjpc.2017.01.084 E 晒 亍嚣 基于 MATLAB的函数图像绘制方法 张笑笑 一,童 键 z (1湖南省长沙市第一中学 湖南 长沙 410() ...

  5. relu,sigmoid,tanh函数图像(python)

    relu,sigmoid,tanh函数图像(python) 1.导入工具包 import math import matplotlib.pyplot as plt import numpy as np ...

  6. python海龟库教学

    海龟库: 海龟绘图 "小海龟"turtle是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数 ...

  7. python海龟库如何导入,少儿Python编程培训手册系列之——海龟库基础用法

    对于少儿编程来说,最有趣的莫过于绘图了,海龟库模块就是最好的也是最基础的绘图工具. 本文整理收集汇总了一些常见的绘图函数,结合前面系列文章的Python基础语法知识,再加上一些经典的案例,使用&quo ...

  8. 常用激活函数activation function(Softmax、Sigmoid、Tanh、ReLU和Leaky ReLU) 附激活函数图像绘制python代码

    激活函数是确定神经网络输出的数学方程式. 激活函数的作用:给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数. 1.附加到网络中的每个神经元,并根据每个神经元的输入来确定是否应激活. 2 ...

  9. Origin | 自定义函数图像绘制

    文章目录 前言 一.图像绘制 二.图像调整 前言 我们常常会遇到一些函数,可利用Origin简单绘制出函数的曲线. 一.图像绘制 打开Origin软件:在上方工具栏点击绘图-函数图-新建2D函数图,此 ...

最新文章

  1. 输入法项目-用delphi生成GBK 中文编码 表(4~5) GBK/4~5: 0xAA40~0xFEA0(部分) 扩充汉字 包括繁体 0xA840~0xA995(部分) 扩充非汉字...
  2. SQL分组多列统计(GROUP BY后按条件分列统计)
  3. qt combox 向上弹出_一睹芳容!人类首次拍到活的公羊角乌贼 手臂和触须向上飞速穿过水柱...
  4. Linux 关闭网络管理服务
  5. JAVA里plain_Java中POJO及其细分XO、DAO的概念
  6. matlab导弹追踪问题垂直逃逸,综合程序设计 导弹追踪问题 (matlab)
  7. [译] 在浏览器里使用 TenserFlow.js 实时估计人体姿态
  8. Flutter 本地数据库sqflite实战操作
  9. 微信订阅号改回列表显示
  10. 电脑pin码忘了登录不进系统_忘记计算机 PIN 码怎么办?
  11. 数字电路34( 计数器—二进制加计数器)
  12. 计算机学院 名言,计算机系网络毕业名言
  13. 叮咚~您的新年礼物到啦,请查收:虎来喽----Python打造虎年祝福神器
  14. iPhone快速切换表情输入法
  15. 思科配置系统日志服务器配置,思科交换机路由器配置日志服务器脚本
  16. 成功将 戴尔灵越燃7000 II 改装Win7
  17. kotlin完成 Code War 题目 解析分子公式
  18. 基于JAVA前后端分离健身房管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
  19. nvidia显卡相关信息查询
  20. Delegate委托的使用

热门文章

  1. 回看皮尔斯—皮尔斯的逻辑开篇
  2. 开发数字藏品平台的公司
  3. 2021漏洞总结3-优化版检测脚本
  4. 移动互联网十年(建议收藏)
  5. Android材料设计
  6. 如何免费XPS转PDF
  7. 10.Vue.js前端框架:过渡
  8. 显卡驱动装失败问题解决
  9. sqlserver用户登录失败
  10. 坚果pro2MIUI10修改按键功能