当前位置: 首页 > news >正文

【Godot4.3】三角形类

概述

在GDSCript中你想要表示一个平面三角形,只需要设定3个点的位置,也就是3个Vector2就行了,或者一个size()==3PackedVector2Array

但是想要进一步处理三角形,获得它的一些几何特征,比如:某个内角的角度值,角平分线、垂直平分线、中线、高线,还有对应的内接圆、外接圆圆心与半径等,就会变得比较困难。

本篇就讲述如何在Godot4.3中,用类来表示三角形,并获取它的几何特征。

类设计

  • Triangle类用于表示一个二维平面的三角形,可以获取内接圆、外接圆圆心与半径
  • Angle类用来表示一个角,可以获取角平分线、中线和高线
  • Segment类用来表示线段,比如三角形的边,可以获取垂直平分线

目前的设计只是一个初步实现,进一步可能会修改或添加一些方法。

三角形

# 三角形
class Triangle:var point_a:Vector2var point_b:Vector2var point_c:Vector2func _init(point_a:Vector2,point_b:Vector2,point_c:Vector2) -> void:self.point_a = point_aself.point_b = point_bself.point_c = point_c# 获取三角形的点集func get_points() -> PackedVector2Array:var points:PackedVector2Arraypoints.append_array([point_a,point_b,point_c,point_a])return points# 获取角Afunc get_angle_a() -> Angle:return Angle.new(point_a,point_b,point_c)# 获取角Bfunc get_angle_b() -> Angle:return Angle.new(point_b,point_a,point_c)# 获取角Cfunc get_angle_c() -> Angle:return Angle.new(point_c,point_a,point_b)# 重心 - 任意两条中线的交点func gravity_center():var s1 = get_angle_a().get_mid_line()var s2 = get_angle_b().get_mid_line()return Geometry2D.line_intersects_line(s1.start,s1.vec().normalized(),s2.start,s2.vec().normalized())# 垂心 - 任意两条垂线的交点func high_center():var s1 = get_angle_a().get_high_line()var s2 = get_angle_b().get_high_line()return Geometry2D.line_intersects_line(s1.start,s1.vec().normalized(),s2.start,s2.vec().normalized())# 外心 - 任意两条垂直平分线的交点func out_center():var s1 = get_angle_a().seg_ab().mid_vertical_line()var s2 = get_angle_a().seg_bc().mid_vertical_line()return Geometry2D.line_intersects_line(s1.start,s1.vec().normalized(),s2.start,s2.vec().normalized())# 外接圆半径 - 外心与三个顶点距离中最长的一个func out_radius():var c:Vector2 = out_center()# 外心与各顶点的距离var m:float = minf(c.distance_to(point_a),c.distance_to(point_b))m = minf(m,c.distance_to(point_c))return m# 内心(内接圆圆心) - 任意两条角平分线的交点func inner_center() :var s1 = get_angle_a().get_half_angle_line()var s2 = get_angle_b().get_half_angle_line()return Geometry2D.line_intersects_line(s1.start,s1.vec().normalized(),s2.start,s2.vec().normalized())# 内接圆半径 - 内心在三条角平分线上短的那段的长度中最短的一个func inner_radius():var c:Vector2 = inner_center()# 内心与各边的垂直相交点var p1:Vector2 = Geometry2D.get_closest_point_to_segment(c,point_a,point_b)var p2:Vector2 = Geometry2D.get_closest_point_to_segment(c,point_a,point_c)var p3:Vector2 = Geometry2D.get_closest_point_to_segment(c,point_b,point_c)var m:float = minf(c.distance_to(p1),c.distance_to(p2))m = minf(m,c.distance_to(p3))return m

# 内角
class Angle:# 点var point_a:Vector2var point_b:Vector2var point_c:Vector2# 永远以point_a作为角的顶点func _init(point_a:Vector2,point_b:Vector2,point_c:Vector2) -> void:self.point_a = point_aself.point_b = point_bself.point_c = point_c# 线段abfunc seg_ab() -> Segment:return Segment.new(point_a,point_b)# 线段abfunc seg_ac() -> Segment:return Segment.new(point_a,point_c)# 线段abfunc seg_bc() -> Segment:return Segment.new(point_b,point_c)# 获取夹角(弧度)func angle() -> float:return abs(seg_ab().vec().angle_to(seg_ac().vec()))# 获取角平分线func get_half_angle_line() -> Segment:var ang = seg_ab().vec().angle_to(seg_ac().vec())var len = maxf(seg_ab().vec().length(),seg_ac().vec().length()) # 取较长边长度var p = point_a + seg_ab().vec().normalized().rotated(ang/2.0) * lenvar p1 = Geometry2D.line_intersects_line(point_b,seg_bc().vec(),point_a,point_a.direction_to(p))return Segment.new(point_a,p1)# 获取中线func get_mid_line() -> Segment:return Segment.new(point_a,seg_bc().mid_point())# 获取高线func get_high_line() -> Segment:var p = Geometry2D.get_closest_point_to_segment_uncapped(point_a,point_b,point_c)return Segment.new(point_a,p)

线段

# 线段
class Segment:var start:Vector2var end:Vector2func _init(p1:Vector2,p2:Vector2) -> void:start = p1end = p2# 返回向量func vec() -> Vector2:return end - start# 获取点集func points() -> PackedVector2Array:var arr:PackedVector2Arrayarr.append_array([start,end])return arr# 获取中点func mid_point() -> Vector2:return start.lerp(end,0.5)# 垂直平分线func mid_vertical_line() -> Segment:var half_normal = vec().rotated(deg_to_rad(90))/2.0var p1 = mid_point() + half_normalvar p2 = mid_point() - half_normalreturn Segment.new(p1,p2)

测试

创建和绘制三角形

extends Node2Dvar t1:Triangle = Triangle.new(Vector2(100,100),Vector2(200,100),Vector2(150,200))func _process(delta: float) -> void:t1.point_c = get_global_mouse_position()queue_redraw()func _draw() -> void:draw_polyline(t1.get_points(),Color.WHITE,1)

中线和重心

func _draw() -> void:draw_polyline(t1.get_points(),Color.WHITE,1)# 三条中线var l1 = t1.get_angle_a().get_mid_line().points()var l2 = t1.get_angle_b().get_mid_line().points()var l3 = t1.get_angle_c().get_mid_line().points()draw_polyline(l1,Color.AQUAMARINE,1)draw_polyline(l2,Color.AQUAMARINE,1)draw_polyline(l3,Color.AQUAMARINE,1)# 重心draw_circle(t1.gravity_center(),3,Color.BROWN)

在这里插入图片描述

角平分线和内心

func _draw() -> void:draw_polyline(t1.get_points(),Color.WHITE,1)# 三条角平分线var l4 = t1.get_angle_a().get_half_angle_line().points()var l5 = t1.get_angle_b().get_half_angle_line().points()var l6 = t1.get_angle_c().get_half_angle_line().points()draw_polyline(l4,Color.AQUAMARINE,1)draw_polyline(l5,Color.AQUAMARINE,1)draw_polyline(l6,Color.AQUAMARINE,1)# 重心draw_circle(t1.inner_center(),3,Color.BROWN)draw_circle(t1.inner_center(),t1.inner_radius(),Color.YELLOW,false,1)

在这里插入图片描述

垂直平分线和外心

func _draw() -> void:draw_polyline(t1.get_points(),Color.WHITE,1)# 三条边的垂直平分线var l4 = t1.get_angle_a().seg_ab().mid_vertical_line().points()var l5 = t1.get_angle_a().seg_bc().mid_vertical_line().points()var l6 = t1.get_angle_a().seg_ac().mid_vertical_line().points()draw_polyline(l4,Color.AQUAMARINE,1)draw_polyline(l5,Color.AQUAMARINE,1)draw_polyline(l6,Color.AQUAMARINE,1)# 外心draw_circle(t1.out_center(),3,Color.BROWN)draw_circle(t1.out_center(),t1.out_radius(),Color.YELLOW,false,1)

在这里插入图片描述

高线和垂心

func _draw() -> void:draw_polyline(t1.get_points(),Color.WHITE,1)# 三条边的垂直平分线var l4 = t1.get_angle_a().get_high_line().points()var l5 = t1.get_angle_b().get_high_line().points()var l6 = t1.get_angle_c().get_high_line().points()draw_polyline(l4,Color.AQUAMARINE,1)draw_polyline(l5,Color.AQUAMARINE,1)draw_polyline(l6,Color.AQUAMARINE,1)# 垂心if t1.high_center():draw_circle(t1.high_center(),3,Color.BROWN)

在这里插入图片描述

总结

本文所述,是三角形几何特性获得的初步,API肯定会大改,只是作为初步试验成功的结果。

三角形是一种特殊的多边形,一些几何特性值得深入研究。


http://www.mrgr.cn/news/34677.html

相关文章:

  • test 是 JavaScript 中正则表达式对象 (RegExp) 的一种方法,用于测试一个字符串是否匹配某个正则表达式
  • 低空载功耗,高能源利用率 BDA5-20W BOSHIDA DCDC
  • vue内置方法总结
  • 线性代数(第三章:向量)
  • 工程师 - etc/hosts文件
  • 快速入门Zookeeper
  • JS的链判断符有几种写法,有哪些用法?
  • # 深度学习笔记(9)huggingface 构建数据集
  • kubernetes网络(三)之bird的路由反射器的使用
  • 大数据新视界 --大数据大厂之 Reactjs 在大数据应用开发中的优势与实践
  • npm、yarn、pnpm 最新国内镜像源设置和常见问题解决
  • Axure精选各类组件案例集锦:设计灵感与实战技巧
  • 速盾:网页游戏部署高防服务器有什么优势?
  • Spring MVC 执行流程
  • FortiGate 硬盘格式化指南
  • C++11新特性和扩展(1)
  • LLMs之Qwen:Qwen2.5的简介、安装和使用方法、案例应用之详细攻略
  • 防护装备穿戴与否检测系统源码分享
  • Algo-Lab 2 Stack Queue ADT
  • GUI编程之MATLAB入门详解(01)
  • 开箱元宇宙| 探索 Great Entertainment Group 如何利用 Web3 和数字创新重新定义活动体验
  • poi生成的ppt,powerPoint打开提示内容错误解决方案
  • Qanything 2 0源码解析系列1:新建知识库
  • 【OpenAI o1背后技术】Sef-play RL:LLM通过博弈实现进化
  • JAVA_17
  • 大数据系统调优:从DAG到单机