概述
在示意图绘制过程中或者测试过程中,可能需要标记点的索引。
最常见的形式就是用一个圆圈作为背景,用阿拉伯数字作为索引。
实现的重点是动态计算背景圆的半径。原理是,获取字符串的矩形,取对角线长度的一半作为外接圆的半径。
系列目录
- 0.概述
- 1.绘制简单图形
- 2.设定绘图变换
- 3.绘制纹理
- 4.绘制样式盒
- 5.绘制字符和字符串
- 6.TextLine和TextParagraph详解
- 7.自定义节点TextBoard
- 8.绘制点索引
- 9.绘制表格
绘图函数实现
# 绘制带有编号的圆,用于标记几何图形顶点
func draw_point_idx(canvas:RID,pos:Vector2,index:int,bg_color:=Color.YELLOW,color:=Color.BLACK,font_size:=16,font:Font = ThemeDB.fallback_font):
# 构造TextLine
var text = TextLine.new()
text.add_string(str(index),font,font_size) # 按设置的字体和字号添加编号
var offset_pos = pos - text.get_size()/2.0 # 文本矩形中心对齐到pos
# 文本的矩形区域
var rect = Rect2(offset_pos,text.get_size())
# 半径 = 对角线长度的一半
var r = text.get_size().length()/2.0
# 绘制外接圆
draw_circle(rect.get_center(),r,bg_color)
## 绘制文本矩形区域
#draw_rect(rect,Color.DARK_GRAY)
# 绘制字符串
text.draw(canvas,offset_pos,color)
测试1
extends Node2D
var points:PackedVector2Array
func _ready() -> void:
for i in range(6):
points.append(Vector2(300,200) + Vector2.RIGHT.rotated(deg_to_rad(360.0/6 * i)) * 100)
func _draw() -> void:
draw_colored_polygon(points,Color.YELLOW_GREEN)
for i in range(points.size()):
draw_point_idx(get_canvas_item(),points[i],i,Color.YELLOW,Color.BLACK,10)
效果:
测试2
extends Node2D
var points:PackedVector2Array
func _ready() -> void:
for i in range(6):
points.append(Vector2(300,200) + Vector2.RIGHT.rotated(deg_to_rad(360.0/6 * i)) * 100)
points.append(Vector2(300,200) + Vector2.RIGHT.rotated(deg_to_rad(360.0/6 * i)) * 50)
func _draw() -> void:
draw_colored_polygon(points,Color.YELLOW_GREEN)
for i in range(points.size()):
draw_point_idx(get_canvas_item(),points[i],i,Color.YELLOW,Color.BLACK,10)
测试3
extends Node2D
var points:PackedVector2Array
func _ready() -> void:
var pos = Vector2(500,300)
var right = Vector2.RIGHT
var step = 30
var r1 = 200
var r2 = 160
for i in range(step):
var ag = deg_to_rad(360.0/step)
points.append(pos + right.rotated(ag * i) * r1)
points.append(pos + right.rotated(ag * i) * r2)
func _draw() -> void:
draw_colored_polygon(points,Color.YELLOW_GREEN)
for i in range(points.size()):
draw_point_idx(get_canvas_item(),points[i],i,Color.YELLOW,Color.BLACK,10)
实现任意文本标记
修改一下函数的参数,就可以实现任意文本的绘制。
# 绘制带有文本的圆,用于标记几何图形顶点索引或显示坐标等
func draw_point_idx(canvas:RID,pos:Vector2,string:String,bg_color:=Color.YELLOW,color:=Color.BLACK,font_size:=16,font:Font = ThemeDB.fallback_font):
# 构造TextLine
var text = TextLine.new()
text.add_string(string,font,font_size) # 按设置的字体和字号添加编号
var offset_pos = pos - text.get_size()/2.0 # 文本矩形中心对齐到pos
# 文本的矩形区域
var rect = Rect2(offset_pos,text.get_size())
# 半径 = 对角线长度的一半
var r = text.get_size().length()/2.0
# 绘制外接圆
draw_circle(rect.get_center(),r,bg_color)
## 绘制文本矩形区域
#draw_rect(rect,Color.DARK_GRAY)
# 绘制字符串
text.draw(canvas,offset_pos,color)
测试代码:
extends Node2D
var points:PackedVector2Array
var pos = Vector2(500,300)
var right = Vector2.RIGHT
var step = 30
var r1 = 200
var r2 = 160
func _ready() -> void:
for i in range(step):
var ag = deg_to_rad(360.0/step)
points.append(pos + right.rotated(ag * i) * r1)
points.append(pos + right.rotated(ag * i) * r2)
func _draw() -> void:
draw_colored_polygon(points,Color.YELLOW_GREEN)
draw_point_idx(get_canvas_item(),pos,"C",Color(Color.YELLOW,0.5),Color.BLACK,10)
for i in range(points.size()):
draw_point_idx(get_canvas_item(),points[i],str(i),Color(Color.YELLOW,0.5),Color.BLACK,10)
绘制效果:
综合实例
extends Node2D
var points:PackedVector2Array
var pos = Vector2(500,300)
var right = Vector2.RIGHT
var step = 12
var r1 = 200
func _ready() -> void:
for i in range(step):
var ag = deg_to_rad(360.0/step)
var p = pos + right.rotated(ag * i) * r1
points.append(p)
func _draw() -> void:
draw_arc(pos,r1,0,TAU,100,Color.AQUAMARINE,1) # 外接圆
draw_colored_polygon(points,Color.YELLOW_GREEN) # 多边形
# 按顺序标记多边形顶点
for i in range(points.size()):
draw_line(pos,points[i],Color.DARK_GREEN,1) # 圆心到多边形顶点的连线
draw_point_idx(get_canvas_item(),points[i],str(i),Color(Color.YELLOW,0.5),Color.BLACK,10)
# 标记圆心
draw_point_idx(get_canvas_item(),pos,"圆心",Color(Color.YELLOW,0.5),Color.BLACK,10)
# 标记单个角度
var ang = TAU/step
draw_arc(pos,30,0,ang,100,Color.DARK_GREEN,1)
draw_point_idx(get_canvas_item(),pos + right.rotated(ang/2.0) * 40, "%s°" % str(rad_to_deg(ang)),Color(Color.YELLOW,0.0),Color.BLACK,10)
绘制效果:
总结
- 标记和绘制点索引是一种很常用且重要的效果
- 本文只是涉及了点索引在几何图形上的使用,实际上可以将它使用在类似标记AStar路径点这样的功能上,让原本抽象的内容一下子变得清晰