概述
平面图形,除了常规的线性变换:平移、缩放、旋转、斜切之外。还可以模仿在三维空间旋转、透视等等。
矩形绕纵对称轴旋转实点的轨迹
- 绕对称旋转是个特殊情况,轨迹是圆也是为了便于理解。更实际的情况应该是椭圆。
- 非对称轴旋转的情况轨迹更可能是同心椭圆。
- 矩形更是个特殊情况,在一个矩形包围盒中的多边旋转,更是多个同心或非同心椭圆。
测试代码
@tool
extends Node2D
var rect = Rect2(-50,-50,100,100) # 透视图形
var points = ShapeTests.get_rect_points(rect)
var uvs = Points2D.Vec2Arr("1,0 0,0 0,1 1,1")
@export_range(-360.0,360.0,1.0) var theta = 0:
set(val):
theta = val
queue_redraw()
@export var texture:Texture2D:
set(val):
texture = val
queue_redraw()
func _draw() -> void:
var top_c = rect.position + Vector2(rect.size.x/2.0,0) # 顶部中点
var bot_c = rect.end - Vector2(rect.size.x/2.0,0) # 底部中点
var half_w = rect.size/2.0
#draw_colored_polygon(points,Color.AQUAMARINE)
var new_points = points.duplicate()
new_points[0] = top_c + Vector2.LEFT.rotated(deg_to_rad(theta)) * half_w
new_points[1] = top_c + Vector2.RIGHT.rotated(deg_to_rad(theta)) * half_w
new_points[2] = bot_c + Vector2.RIGHT.rotated(deg_to_rad(-theta)) * half_w
new_points[3] = bot_c + Vector2.LEFT.rotated(deg_to_rad(-theta)) * half_w
draw_colored_polygon(new_points,Color.AQUAMARINE,uvs,texture)
draw_circle(top_c,3,Color.ORANGE_RED)
draw_circle(bot_c,3,Color.ORANGE_RED)
实现效果:
但是贴图会发生错误:
总结函数
# 将矩形沿Y轴旋转
func rotate_y(rect:Rect2,theta:float) -> PackedVector2Array:
var ang = deg_to_rad(theta)
var top_c = rect.position + Vector2(rect.size.x/2.0,0) # 顶部中点
var bot_c = rect.end - Vector2(rect.size.x/2.0,0) # 底部中点
var half_w = rect.size/2.0
var points = ShapeTests.get_rect_points(rect)
points[0] = top_c + Vector2.LEFT.rotated(ang) * half_w
points[1] = top_c + Vector2.RIGHT.rotated(ang) * half_w
points[2] = bot_c + Vector2.RIGHT.rotated(-ang) * half_w
points[3] = bot_c + Vector2.LEFT.rotated(-ang) * half_w
return points
# 将矩形沿X轴旋转
func rotate_x(rect:Rect2,theta:float) -> PackedVector2Array:
var ang = deg_to_rad(theta)
var left_c = rect.position + Vector2(0,rect.size.y/2.0) # 顶部中点
var right_c = rect.end - Vector2(0,rect.size.y/2.0) # 底部中点
var half_h = rect.size/2.0
var points = ShapeTests.get_rect_points(rect)
points[0] = left_c + Vector2.UP.rotated(ang) * half_h
points[1] = left_c + Vector2.DOWN.rotated(ang) * half_h
points[2] = right_c + Vector2.DOWN.rotated(-ang) * half_h
points[3] = right_c + Vector2.UP.rotated(-ang) * half_h
return points
注意:其实上面的代码中有一个Bug,就是half_w = rect.size/2.0
和half_h = rect.size/2.0
,但是就是这个Bug莫名其妙的导致了边长不等的矩形旋转的的完美,有时候就是这样,哈哈哈…你根本不知道你的代码为什么顺利运行。
上述两个新函数已经作为静态函数库ShapeTests
的静态方法,可以直接调用。