把附录1的代码复制到pc.py文件中,就是极坐标系模块。
最简单的极坐标系一元二次函数ρ=θ²的图象(作图代码附录2)。
ρ=θ²函数的图象是一个轴对称图形,对称轴是极轴所在的直线。
ρ=(θ+a)²的图象,例如ρ=(θ+1)²的图象(作图代码附录3)和ρ=(θ-1)²的图象(作图代码附录4)。
ρ=(θ+1)²的图象
ρ=(θ-1)²的图象
ρ=(θ+a)²的图象与ρ=θ²的图象大小和形状都一样,但对称轴变成了θ=-a所在的直线。
ρ=kθ²(k>0)的图象,例如ρ=(1/2)θ²的图象(作图代码附录5).
ρ=kθ²(k>0)的图象与ρ=θ²的图象形状一样,大小伸缩了。
ρ=kθ²+b(k>0)的图象,分开2种情况,b>0例如ρ=θ²+30的图象(作图代码附录6).
b<0例如ρ=(1/2)θ²-20(θ≤-sqrt(40)或θ≥sqrt(40))的图象(作图代码附录7).
可见,当b>0时,函数图象在ρ=b的圆外;当b<0时,函数图象过极点。
ρ=kθ²+b(k<0,b>0)的图象,例如ρ=-θ²+400(θ≥-20 and θ≤20)的图象(作图代码附录8)。
可见,ρ=kθ²+b(k<0,b>0)是在ρ=b圆内的闭环曲线。
例题1:制作ρ=2(θ+1)²+6的图象。
解:作图如下(作图代码附录9).
练习题:制作ρ=2(θ+1)²-6和ρ=-2(θ+1)²+400的图象。
附录1:
'''极坐标
@作者 码老师
@微信公众号 学思营 ID:xuesying
@公司 深圳五行星软件有限公司
@日期 2021-5-18
@使用方法
注意:要从内圈到外圈,否则可能出错。
1、导入海龟画图并初始化窗口和画布,例如:
import turtle as t
t.setup(600,600)
t.screensize(400,400)
t.shape("turtle")
2、导入本模块:
from pc import *
3、用下面函数:
build(aTurtle, axisUnt = None, draw = True):
@aTurtle 一个海龟
@axisUnt 极轴数值与像素对应元组
@draw 是否绘制坐标与暗线
极坐标坐标系,例如:
build(t)
4、使用模块进行画单调函数轨迹、直线和打点
(1)画函数轨迹
第一步:定义一个单值极坐标函数函数例如:
def fun(st):
return 1+st
第二步:根据fun(st)≥0,确定自变量取值范围:
st1, st2
第四步:调用下面函数:
trace(aTurtle, st1, st2, fun):
@aTurtle 一个海龟
@st1 自变量一端点值,单位弧度
@st2 自变量另一端点值,单位弧度
@fun 极坐标函数
画函数轨迹,例如:
#阿基米德螺线
def fun(st):
return pi/2 + st
trace(t, 50, -50, fun)
(2)画直线段
第一步:获取x,y的取值范围:
minx, maxx, miny, maxy = getRange()
第二步:调用下面函数:
line(aTurtle, x1, y1, x2, y2):
@aTurtle 一个海龟
@x1,y1 始点
@x2,y2 终点
画直线段,例如画对角线:
line(t, minx, miny, maxx, maxy)
(3)打圆点
第一步:获取x,y的取值范围:
minx, maxx, miny, maxy = getRange()
第二步:调用下面函数:
circularDot(aTurtle, x, y, *color, size=None):
@aTurtle 一个海龟
@x,y 坐标
@size 圆点大小
@color 圆点颜色
打圆点,例如下降对角线打点:
x, y = minx, maxy
size = 1
while True:
if x > maxx or y < miny:
break
circularDot(t, x, y, size, "red")
x += 1
y -= 1
size += 1
'''
#导入数学模块
from math import *
#导入分数
from fractions import Fraction
#坐标轴线宽
axisWidth = 1
#坐标轴和坐标点颜色
axisColor = "black"
#坐标箭头
axisTurtle = "classic"
#箭头大小 原来四分之一 轮廓线1
axisShapesize = (0.8, 0.8, 1)
#极轴单位(整数)及其对应的像素大小(整数) 1对应10像素
axisUnit = [1, 10]
#底色圆线宽
circleWidth = 1
#底色圆线色 浅蓝
circleColor = "#EFEFFF"
#数点线长
markLen = 5
#数字字体
markFont=("Arial", 8, "normal")
#画布矩形
worldcoordinates=None
#检测极轴单位
def __checkUnit(unt):
if unt != None and len(unt) == 2:
return isinstance(unt[0],int) and isinstance(unt[1],int)
return False
#建立极坐标系
def build(aTurtle, axisUnt = None, draw=True):
'''极坐标系绘图
@aTurtle 一个海龟
@axisUnt 极轴单位,数值与像素对应元组'''
#数量与像素的对应关系
if __checkUnit(axisUnt):
axisUnit[0] = axisUnt[0]
axisUnit[1] = axisUnt[1]
#画布矩形
global worldcoordinates, step
temp = aTurtle.screensize()
worldcoordinates = (-temp[0]/2,-temp[1]/2,temp[0]/2,temp[1]/2)
if not draw:
return
#保持海龟原来的参数后设置参数
speed = aTurtle.speed()
aTurtle.speed(0)
width = aTurtle.pensize()
pencolor = aTurtle.pencolor()
shape = aTurtle.shape()
shapesize = aTurtle.shapesize()
isdown = aTurtle.isdown()
pos = aTurtle.pos()
heading =aTurtle.heading()
#画底色圆线
if isdown:
aTurtle.up()
aTurtle.seth(90)
for i in range(axisUnit[1], int(worldcoordinates[2])+1, axisUnit[1]):
aTurtle.pencolor(circleColor)
aTurtle.pensize(circleWidth)
aTurtle.setpos(i,0)
aTurtle.down()
aTurtle.circle(i)
aTurtle.up()
aTurtle.pencolor(axisColor)
aTurtle.pensize(axisWidth)
aTurtle.down()
aTurtle.sety(markLen)
aTurtle.up()
aTurtle.sety(-markLen-markFont[1]) #还要下降字体高度
aTurtle.write(i//axisUnit[1]*axisUnit[0], align="center", font = markFont)
#30°分割线
aTurtle.pencolor(circleColor)
aTurtle.pensize(circleWidth)
for i in range(1, 12, 1):
aTurtle.setpos(0,0)
aTurtle.seth(30*i)
aTurtle.down()
aTurtle.fd(worldcoordinates[2])
aTurtle.up()
#画坐标
aTurtle.pencolor(axisColor)
aTurtle.pensize(axisWidth)
aTurtle.shape(axisTurtle)
aTurtle.shapesize(*axisShapesize)
aTurtle.up()
aTurtle.setpos(0, 0)
aTurtle.down()
aTurtle.setx(worldcoordinates[2])
aTurtle.seth(0)
aTurtle.stamp()
aTurtle.up()
#标注极点
aTurtle.setpos(-markLen//2, -markFont[1]//2)
aTurtle.write("O", align="right", font = markFont)
#恢复海龟原来的设置参数
aTurtle.speed(speed)
aTurtle.shape(shape)
aTurtle.pensize(width)
aTurtle.pencolor(pencolor)
aTurtle.shapesize(*shapesize)
aTurtle.setpos(*pos)
aTurtle.seth(heading)
if isdown:
aTurtle.down()
#检查是否已经初始化
def __checkBuild():
if worldcoordinates == None:
print("还没有初始化坐标系,请调用build(aTurtle, axisUnt = None, draw = True)函数画坐标系。")
return False
else:
return True
#屏幕上进1像素实际的值之间的转换
def __pixchange():
#屏幕上进1像素实际的值之间的转换
dx, udx, dy, udy = Fraction(*axisUnit), Fraction(axisUnit[1], axisUnit[0]), Fraction(*axisUnit), Fraction(axisUnit[1], axisUnit[0])
#x坐标作图范围
minx, maxx = dx * worldcoordinates[0], dx * worldcoordinates[2]
#y坐标作图范围
miny, maxy = dy * worldcoordinates[1], dy * worldcoordinates[3]
return dx, udx, dy, udy, minx, maxx, miny, maxy
#把极坐标变直角坐标
def __change(r, st):
return r*cos(st), r*sin(st)
#获取差级,1像素对应的弧度
def __getStep(r=0):
if r<axisUnit[1]*2:
r=axisUnit[1]*2
return axisUnit[0]/(r*axisUnit[1])
#函数轨迹
def trace(aTurtle, st1, st2, fun):
'''函数轨迹
@aTurtle 一个海龟
@st1 自变量一端点值
@st2 自变量另一端点值
@fun 极坐标系函数'''
#自变量检查
if st1 == st2:
print("自变量不可以相等")
return False
#检查是否已经画坐标
if not __checkBuild():
return False
#保持海龟落笔状态
isdown = aTurtle.isdown()
speed = aTurtle.speed()
aTurtle.speed(0)
pos = aTurtle.pos()
if isdown:
aTurtle.up()
#递增还是递减
if st1 > st2:
one=-1
else:
one=1
#屏幕上进1像素实际的值之间的转换
dx, udx, dy, udy, minx, maxx, miny, maxy = __pixchange()
#起点
st = st1
r = fun(st1)
x, y = __change(r, st) #变成直角坐标
if x >= minx and x<= maxx and y >= miny and y<= maxy:
aTurtle.setpos(udx*x, udy*y)
aTurtle.down()
#描图
while True:
st += __getStep(r)*one
if (one==1 and st > st2) or (one==-1 and st<st2): #过了终点
break
r = fun(st)
x, y = __change(r, st)
if x >= minx and x<= maxx and y >= miny and y<= maxy:
aTurtle.setpos(udx*x, udy*y)
if not aTurtle.isdown():
aTurtle.down()
else:
if aTurtle.isdown():
aTurtle.setpos(udx*x, udy*y)
aTurtle.up()
if aTurtle.isdown():
aTurtle.up()
aTurtle.setpos(*pos)
aTurtle.speed(speed)
#恢复下笔状态
if isdown:
aTurtle.down()
return True
#作图范围
def getRange():
'''作图范围
@return x坐标最小值,x坐标最大值,y坐标最小值,y坐标最大值'''
#检查是否已经画坐标
if not __checkBuild():
return None
#屏幕上进1像素实际的值之间的转换
dx, udx, dy, udy, minx, maxx, miny, maxy = __pixchange()
return minx, maxx, miny, maxy
#作图范围字符串
def __rangestr(minx, maxx, miny, maxy):
return "%s≤x≤%s,%s≤y≤%s" % (str(minx),str(maxx),str(miny),str(maxy))
#画线段
def line(aTurtle, x1, y1, x2, y2):
'''画线段
@aTurtle 一个海龟
@x1,y1 始点
@x2,y2 终点'''
#检查是否已经画坐标
if not __checkBuild():
return False
#屏幕上进1像素实际的值之间的转换
dx, udx, dy, udy, minx, maxx, miny, maxy = __pixchange()
if min(x1, x2) < minx or max(x1, x2) > maxx or min(y1, y2) < miny or max(y1, y2) > maxy:
print("有端点不在作图范围(%s)内!" % __rangestr(minx, maxx, miny, maxy))
return False
#保持海龟落笔状态
isdown = aTurtle.isdown()
pos = aTurtle.pos()
speed = aTurtle.speed()
aTurtle.speed(0)
if isdown:
aTurtle.up()
aTurtle.setpos(udx*x1, udy*y1)
aTurtle.down()
aTurtle.setpos(udx*x2, udy*y2)
aTurtle.up()
aTurtle.setpos(*pos)
aTurtle.speed(speed)
if isdown:
aTurtle.down()
return True
#打圆点
def circularDot(aTurtle, x, y, *color, size=None):
'''打点
@aTurtle 一个海龟
@x,y 坐标
@size 圆点大小
@color 圆点颜色'''
#检查是否已经画坐标
if not __checkBuild():
return False
#屏幕上进1像素实际的值之间的转换
dx, udx, dy, udy, minx, maxx, miny, maxy = __pixchange()
if x< minx or x > maxx or y < miny or y > maxy:
print("该点点不在作图范围(%s)内!" % __rangestr(minx, maxx, miny, maxy))
return False
isdown = aTurtle.isdown()
pos = aTurtle.pos()
speed = aTurtle.speed()
aTurtle.speed(0)
if isdown:
aTurtle.up()
aTurtle.setpos(udx*x, udy*y)
if color == None:
aTurtle.dot(size)
else:
aTurtle.dot(size, *color)
aTurtle.setpos(*pos)
aTurtle.speed(speed)
if isdown:
aTurtle.down()
return True
if __name__ == "__main__":
import turtle as t
t.setup(600,600)
t.screensize(400,400)
t.shape("turtle")
build(t) #, worldcoordinates=(0,0,400,400))
#阿基米德螺线
def fun(st):
return pi/2+st
t.pencolor("red")
trace(t, -pi/2, -pi/2+6*pi,fun)
t.ht()
t.mainloop()
附录2:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
def fun(st):
return st**2
t.pensize(2)
t.pencolor("blue")
trace(t, 0, -1-6*pi, fun)
t.pencolor("red")
trace(t, 0, 1+6*pi, fun)
t.ht()
附录3:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
a=1
def fun(st):
return (st+a)**2
t.pensize(2)
t.pencolor("blue")
trace(t, -a, -1-6*pi-a, fun)
t.pencolor("red")
trace(t, -a, 1+6*pi-a, fun)
t.ht()
附录4:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
a=-1
def fun(st):
return (st+a)**2
t.pensize(2)
t.pencolor("blue")
trace(t, -a, -1-6*pi-a, fun)
t.pencolor("red")
trace(t, -a, 1+6*pi-a, fun)
t.ht()
附录5:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
k=1/2
def fun(st):
return k*st**2
t.pensize(2)
t.pencolor("blue")
trace(t, 0, -1-6*pi,fun)
t.pencolor("red")
trace(t, 0, 1+6*pi, fun)
t.ht()
附录6:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
k=1
b=30
def fun(st):
return k*st**2+b
t.pensize(2)
t.pencolor("blue")
trace(t, 0, -1-6*pi,fun)
t.pencolor("red")
trace(t, 0, 1+6*pi, fun)
t.ht()
附录7:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[20, 20])
k=1/2
b=-20
def fun(st):
return k*st**2+b
t.pensize(2)
t.pencolor("blue")
trace(t, -40**.5, -1-6*pi-40**.5, fun)
t.up()
t.pencolor("red")
trace(t, 40**.5, 40**.5+1+6*pi, fun)
t.ht()
附录8:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[30, 20])
def fun(st):
return -st**2+400
t.pensize(2)
t.pencolor("blue")
trace(t, -20, 0, fun) #内到外
t.pencolor("red")
trace(t, 20, 0, fun)
t.ht()
附录9:
import turtle as t
t.setup(700,700)
t.screensize(600,600)
t.shape("turtle")
from pc import *
build(t, axisUnt =[60, 20])
k=2
a=1
b=6
def fun(st):
return k*(st+a)**2+6
t.pensize(2)
t.pencolor("blue")
trace(t, -1, -2-6*pi, fun) #内到外
t.pencolor("red")
trace(t, -1, 6*pi, fun)
t.ht()