猫史档案馆


【Python作品分享】初中平面直角坐标系中单值函数轨迹、画直线和打点【教程贴】

用户:e国阳光e国阳光查看:0 回复:0 评论:0 创建时间:2021-03-06T16:35:56


【作品展示】

center_image

 

【作品介绍】

更多课程5xstar、co'm

 

【作品源代码】

'''初中平面直角坐标系中单值函数轨迹、画直线和打点

@作者  码老师
@微信公众号  学思营 ID:xuesying
@公司  深圳五行星软件有限公司
@网喵期  2020-12-19
@使用方法

1、导入海龟画图并初始化窗口和画布,例如:

    import turtle as t

    t.setup(600,600)

    t.screensize(400,400)

    t.shape("turtle")

    

2、导入本模块:

    from rcs import *



3、用下面函数:

    build(aTurtle, xUnt = None, yUnt = None, wc = None):

    @aTurtle 一个海龟

    @xUnt  x轴数值与像素对应元组

    @yUnt  y轴数值与像素对应元组

    @wc 自定义坐标元组(llx, lly, urx, ury)

        @llx -- 一个数值, 画布左下角的 x-坐标(像素)

        @lly -- 一个数值, 画布左下角的 y-坐标

        @urx -- 一个数值, 画面右上角的 x-坐标

        @ury -- 一个数值, 画布右上角的 y-坐标

    画平面直角坐标系,例如:

    build(t) #, worldcoordinates=(0,0,400,400))



4、使用模块进行画单调函数轨迹、直线和打点  

(1)画函数轨迹

第一步:定义一个单调函数例如:

        def fun(x):

            return 5*x + 3

第二步:获取x,y的取值范围:

        minx, maxx, miny, maxy = getRange()

第三步(可选):根据x,y的取值范围和函数的实际要求,确定自变量取值范围:

       x1,x2

第四步:调用下面函数:

        trace(aTurtle, x1, x2, fun):

        @aTurtle 一个海龟

        @x1 自变量一端点值

        @x2 自变量另一端点值

        @fun 单调函数

        画函数轨迹,例如:

    #一元一次函数

    def fun(x):

        return 2*x + 1

    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, size=None, *color):

        @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 fractions import Fraction


#坐标轴线宽

axisWidth = 1

#坐标轴和坐标点颜色

axisColor = "black"

#坐标箭头

axisTurtle = "classic"

#箭头大小 原来四分之一 轮廓线1

axisShapesize = (0.8, 0.8, 1)

#数轴单位(整数)及其对应的像素大小(整数) 1对应10像素

xUnit = [1, 20]

yUnit = [1, 20]

#方格线宽

squareWidth = 1

#方格线色 浅蓝

squareColor = "#EFEFFF"

#数点线长

markLen = 5

#数字字体

markFont = ("Arial", 8, "normal")

#坐标系,调用build后才有值

worldcoordinates = None


#检测数轴单位

def __checkUnit(unt):

    if unt != None and len(unt) == 2:

        return isinstance(unt[0], int) and isinstance(unt[0], int)

    return False


#建立直角坐标系

def build(aTurtle, xUnt=None, yUnt=None, wc=None):
    '''按初中课本使用的直角坐标系绘图

    @aTurtle 一个海龟

    @xUnt  x轴数值与像素对应元组

    @yUnt  y轴数值与像素对应元组

    @wc 自定义坐标元组(llx, lly, urx, ury)

        @llx -- 一个数值, 画布左下角的 x-坐标(像素)

        @lly -- 一个数值, 画布左下角的 y-坐标

        @urx -- 一个数值, 画面右上角的 x-坐标

        @ury -- 一个数值, 画布右上角的 y-坐标'''

    #保持海龟原来的参数后设置参数

    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 __checkUnit(xUnt):

        xUnit[0] = xUnt[0]

        xUnit[1] = xUnt[1]

    if __checkUnit(yUnt):

        yUnit[0] = yUnt[0]

        yUnit[1] = yUnt[1]

    global worldcoordinates

    #自定义坐标

    if wc != None and len(wc) == 4:

        worldcoordinates = wc

        aTurtle.setworldcoordinates(*worldcoordinates)  # 自定义坐标系

    else:

        temp = aTurtle.screensize()

        worldcoordinates = (-temp[0]/2, -temp[1]/2, temp[0]/2, temp[1]/2)

    #定坐标方向

    xh = worldcoordinates[0] < worldcoordinates[2]

    if xh:  # True从左到右

        x1, x2 = int(worldcoordinates[0]), int(worldcoordinates[2])

    else:

        x1, x2 = int(worldcoordinates[2]), int(worldcoordinates[0])

    yh = worldcoordinates[1] < worldcoordinates[3]

    if yh:  # True从下到上

        y1, y2 = int(worldcoordinates[1]), int(worldcoordinates[3])

    else:

        y1, y2 = int(worldcoordinates[3]), int(worldcoordinates[1])

    #画方格线

    #画与y轴平行的线

    if isdown:

        aTurtle.up()

    for i in range(-xUnit[1], x1, -xUnit[1]):

        aTurtle.pencolor(squareColor)

        aTurtle.pensize(squareWidth)

        aTurtle.setpos(i, y1)

        aTurtle.down()

        aTurtle.sety(y2)

        aTurtle.up()

        aTurtle.sety(0)

        aTurtle.down()

        aTurtle.pencolor(axisColor)

        aTurtle.pensize(axisWidth)

        aTurtle.sety(markLen)

        aTurtle.up()

        if yh:  # 标x数字

            aTurtle.sety(-markLen-markFont[1])  # 还要下降字体高度

        else:

            aTurtle.sety(-markLen//2)  # 无需下降字体高度

        aTurtle.write(i//xUnit[1]*xUnit[0], align="center", font=markFont)

    for i in range(xUnit[1], x2, xUnit[1]):

        aTurtle.pencolor(squareColor)

        aTurtle.pensize(squareWidth)

        aTurtle.setpos(i, y1)

        aTurtle.down()

        aTurtle.sety(y2)

        aTurtle.up()

        aTurtle.sety(0)

        aTurtle.down()

        aTurtle.pencolor(axisColor)

        aTurtle.pensize(axisWidth)

        aTurtle.sety(markLen)

        aTurtle.up()

        if yh:

            aTurtle.sety(-markLen-markFont[1])

        else:

            aTurtle.sety(-markLen//2)

        aTurtle.write(i//xUnit[1]*xUnit[0], align="center", font=markFont)

    #画与x轴平行的线

    for i in range(-yUnit[1], y1, -yUnit[1]):

        aTurtle.pencolor(squareColor)

        aTurtle.pensize(squareWidth)

        aTurtle.setpos(x1, i)

        aTurtle.down()

        aTurtle.setx(x2)

        aTurtle.up()

        aTurtle.setx(0)

        aTurtle.down()

        aTurtle.pencolor(axisColor)

        aTurtle.pensize(axisWidth)

        aTurtle.setx(markLen)

        aTurtle.up()

        if yh:  # 标y数字

            aTurtle.setpos(-markLen//2, i-markFont[1]//2)  # 下降字体高度一半

        else:

            aTurtle.setpos(-markLen//2, i+markFont[1]//2)

        if xh:

            aTurtle.write(i//yUnit[1]*yUnit[0], align="right", font=markFont)

        else:

            aTurtle.write(i//yUnit[1]*yUnit[0], font=markFont)

    for i in range(yUnit[1], y2, yUnit[1]):

        aTurtle.pencolor(squareColor)

        aTurtle.pensize(squareWidth)

        aTurtle.setpos(x1, i)

        aTurtle.down()

        aTurtle.setx(x2)

        aTurtle.up()

        aTurtle.setx(0)

        aTurtle.down()

        aTurtle.pencolor(axisColor)

        aTurtle.pensize(axisWidth)

        aTurtle.setx(markLen)

        aTurtle.up()

        if yh:

            aTurtle.setpos(-markLen//2, i-markFont[1]//2)

        else:

            aTurtle.setpos(-markLen//2, i+markFont[1]//2)

        if xh:

            aTurtle.write(i//yUnit[1]*yUnit[0], align="right", font=markFont)

        else:

            aTurtle.write(i//yUnit[1]*yUnit[0], font=markFont)

    #画坐标

    aTurtle.pencolor(axisColor)

    aTurtle.pensize(axisWidth)

    aTurtle.shape(axisTurtle)

    aTurtle.shapesize(*axisShapesize)

    aTurtle.up()

    aTurtle.setpos(x1, 0)

    aTurtle.down()

    aTurtle.setx(x2)

    if xh:

        aTurtle.seth(0)

    else:

        aTurtle.seth(180)

    aTurtle.stamp()

    aTurtle.up()

    if yh:

        aTurtle.sety(-markLen-markFont[1])

    else:

        aTurtle.sety(-markLen//2)

    aTurtle.write('x', align="center", font=markFont)

    aTurtle.setpos(0, y1)

    aTurtle.down()

    aTurtle.sety(y2)

    if yh:

        if xh:

            aTurtle.seth(90)

        else:

            aTurtle.seth(-90)

    else:

        if xh:

            aTurtle.seth(90)

        else:

            aTurtle.seth(-90)

    aTurtle.stamp()

    aTurtle.up()

    if yh:

        aTurtle.setpos(-markLen//2, y2-markFont[1])

    else:

        aTurtle.setx(-markLen//2)

    if xh:

        aTurtle.write('y', align="right", font=markFont)

    else:

        aTurtle.write('y', font=markFont)

    #标注原点

    if yh:

        aTurtle.setpos(-markLen//2, -markLen-markFont[1])

    else:

        aTurtle.setpos(-markLen//2, -markLen//2)

    if xh:

        aTurtle.write(0, align="right", font=markFont)

    else:

        aTurtle.write(0, 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, xUnt = None, yUnt = None, worldcoordinates = None)函数画坐标")

        return False

    else:

        return True


#屏幕上进1像素实际的值之间的转换

def __pixchange():

    #屏幕上进1像素实际的值之间的转换

    dx, udx, dy, udy = Fraction(
        *xUnit), Fraction(xUnit[1], xUnit[0]), Fraction(*yUnit), Fraction(yUnit[1], yUnit[0])

    #x坐标作图范围

    if worldcoordinates[0] < worldcoordinates[2]:

        minx, maxx = dx * worldcoordinates[0], dx * worldcoordinates[2]

    else:

        minx, maxx = dx * worldcoordinates[2], dx * worldcoordinates[0]

    #y坐标作图范围

    if worldcoordinates[1] < worldcoordinates[3]:

        miny, maxy = dy * worldcoordinates[1], dy * worldcoordinates[3]

    else:

        miny, maxy = dy * worldcoordinates[3], dy * worldcoordinates[1]

    return dx, udx, dy, udy, minx, maxx, miny, maxy


#函数轨迹

def trace(aTurtle, x1, x2, fun):
    '''函数轨迹

    @aTurtle 一个海龟

    @x1 自变量一端点值

    @x2 自变量另一端点值

    @fun 单调函数'''

    #自变量检查

    if x1 == x2:

        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 x1 > x2:  # 交换自变量

        temp = x1

        x1 = x2

        x2 = temp

    #屏幕上进1像素实际的值之间的转换

    dx, udx, dy, udy, minx, maxx, miny, maxy = __pixchange()

    if x2 <= minx or x1 >= maxx:

        print("自变量不在%s到%s范围内!" % (str(minx), str(maxx)))

        return False

    if x1 < minx:

        x1 = minx

    if x2 > maxx:

        x2 = maxx

    #起点

    x = x1

    y = fun(x1)

    if y >= miny and y <= maxy:

        aTurtle.setpos(udx*x, udy*y)

        aTurtle.down()

    #描图

    while True:

        x += dx

        if x > x2:  # 过了终点

            break

        y = fun(x)

        if 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, size=None, *color):
    '''打点

    @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 fun1(x):

        return 2*x + 1

    trace(t, 50, -50, fun1)

    #一元二次函数

    def fun2(x):

        return x**2 + 2*x + 2

    trace(t, 50, -50, fun2)

    #画圆

    def fun3(x):

        return (5**2 - x**2)**0.5

    trace(t, 5, -5, fun3)

    def fun4(x):

        return -(5**2 - x**2)**0.5

    trace(t, 5, -5, fun4)

    #画对角线

    minx, maxx, miny, maxy = getRange()

    line(t, minx, miny, maxx, maxy)

    #打点对角线

    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

    t.mainloop()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 0下一页