强基初中数学&学Python——第九十四课 函数与方程之三十八:自创极坐标系模块及一元二次函数。

 

  把附录1的代码复制到pc.py文件中,就是极坐标系模块。

  最简单的极坐标系一元二次函数ρ=θ²的图象(作图代码附录2)。

 

  ρ=θ²函数的图象是一个轴对称图形,对称轴是极轴所在的直线。

  ρ=+a)²的图象,例如ρ=+1)²的图象(作图代码附录3)和ρ=-1)²的图象(作图代码附录4)。

ρ=+1)²的图象

 

ρ=-1)²的图象

 

  ρ=+a)²的图象与ρ=θ²的图象大小和形状都一样,但对称轴变成了θ=-a所在的直线。

  ρ=²(k>0)的图象,例如ρ=(1/2)θ²的图象(作图代码附录5.

 

  ρ=²(k>0)的图象与ρ=θ²的图象形状一样,大小伸缩了。

  ρ=²+b(k>0)的图象,分开2种情况,b>0例如ρ=θ²+30的图象(作图代码附录6.

 

b<0例如ρ=(1/2)θ²-20(θ≤-sqrt(40)θ≥sqrt(40))的图象(作图代码附录7.

  

  可见,当b>0时,函数图象在ρ=b的圆外;当b<0时,函数图象过极点。

  ρ=²+b(k<0b>0)的图象,例如ρ=²+400(θ≥-20 and  θ≤20)的图象(作图代码附录8)。

 

  可见,ρ=²+b(k<0b>0)是在ρ=b圆内的闭环曲线。

  例题1制作ρ=2(θ+1)²+6的图象。

  解:作图如下(作图代码附录9).

 

  练习题:制作ρ=2(θ+1)²-6ρ=-2(θ+1)²+400的图象。

 

附录1

'''极坐标
@作者  码老师
@微信公众号  学思营 IDxuesying
@公司  深圳五行星软件有限公司
@日期  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()