【Godot4.3】模拟平面图形绕轴或点在空间旋转

概述

平面图形,除了常规的线性变换:平移、缩放、旋转、斜切之外。还可以模仿在三维空间旋转、透视等等。

矩形绕纵对称轴旋转实点的轨迹

  • 绕对称旋转是个特殊情况,轨迹是圆也是为了便于理解。更实际的情况应该是椭圆。
  • 非对称轴旋转的情况轨迹更可能是同心椭圆。
  • 矩形更是个特殊情况,在一个矩形包围盒中的多边旋转,更是多个同心或非同心椭圆。

平面图形模拟空间中绕对称轴旋转示意图

旋转90度的特殊情况

测试代码

@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.0half_h = rect.size/2.0,但是就是这个Bug莫名其妙的导致了边长不等的矩形旋转的的完美,有时候就是这样,哈哈哈…你根本不知道你的代码为什么顺利运行。

上述两个新函数已经作为静态函数库ShapeTests的静态方法,可以直接调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巽星石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值