学习笔记分享

分享与展示个人专业知识学习笔记

0%

turtle字体粗糙定位

不同的字体实现不同,有等宽非等宽,非等宽字体不同字符宽度不同宽高比也各不相同,而且字体尺寸像素是无法直接转换的。因此,今天介绍的方法并非完美的解决方案,只是用于粗糙估算turtle中字符的长宽,用于在字符上绘图进行绘图操作,如圈画文本等。

背景知识

write函数

turtle中用于书写文本的函数为write

1
turtle.write(arg, move=False, align="left", font=("Arial", 8, "normal"))

参数:

  • arg – 要书写到 TurtleScreen 的对象
    如:”something”,123,(1,2),[1,2,3]等

  • move – True/False
    如果 move 为 True,画笔会移动到文本的右下角,这样文字就不会叠在一块了。

  • align – 字符串 “left”, “center” 或 “right”
    align 指定对齐方式 (“left”, “center” 或 right”)

  • font – 一个三元组 (fontname, fontsize, fonttype)
    font 指定字体

作用:

书写文本 arg 指定的字符串到当前海龟位置。

思路

这里有两种思路,都不精确,第一种直接估算,第二种根据宽度估算,各有优劣,仅供参考:

  1. fontsize近似代替宽度,然后用估测的纵横比近似估算高度,得到字符长宽参数,进而确定位置。

  2. 由于每个字宽度不同,所以可以单独绘制每个字符,将move设为True,这样在写每个字符时,画笔会跟着移动,可以记录其始末位置,作差得到每个字符的宽度

代码

这里我们实现了在turtle中对文本部分子串进行圈画的功能,其中两种思路都有涉及。

最后选用记录的宽度作为画圈的直径。另外,因为每个字符高度差不多,所以高度统一采用估算的高度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import turtle

turtle.speed(0)
turtle.delay(0)
turtle.hideturtle()

text = "ACTACGTCAGCTCGTCATCGGTACGTCTCVATGACGTCGT"

# 选取字符串子串位置,闭区间[start_idx, end_idx]
start_idx = 33
end_idx = 36

# pos用于存储对应位置字符的始末x坐标
pos = list()

# 字体设置
font_setting = ("Arial", 16, "normal")

# 不同字体实现不同,且不同字符长宽又不同
# 这里假设字符像素宽度近似fontsize,宽高比为1.5倍
# 如果想更精确,请自己根据特定字体精调参数
aspect_ratio = 1.5
font_width = font_setting[1]
font_height = font_width*aspect_ratio

turtle.penup()
for ch in text:
# 单独绘制每个字符
start = turtle.position()[0]
turtle.write(ch, move=True, font=font_setting)
end = turtle.position()[0]
pos.append((start, end))


# 计算直径半径
d = pos[end_idx][1] - pos[start_idx][0]
r = d/2

# 计算circle函数绘制起点坐标
center_x = (pos[end_idx][1] + pos[start_idx][0])/2
center_y = font_height/2 - r + 1.5

# 设置画笔
turtle.pencolor("red")
turtle.pensize(2)


turtle.setposition(center_x, center_y)
turtle.pendown()
turtle.circle(r)

input("Press Enter to continue...")

demo-1

image-20211216233747578

Note

这里仅用于演示,因此圈画功能简单使用了circle函数,绘制的是圆形,在圈画较长或较短字符串时并不美观,实际使用时可以根据需求自己调整,比如绘制椭圆或方框等其他圈画方式。

创作不易,支持一下吧!