- using Godot;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Godot.Collections;
-
- public partial class TestMask : Node2D
- {
- [Export]
- public Polygon2D PolygonNode;
-
- public List<Vector2[]> Result = new List<Vector2[]>();
- public override void _Ready()
- {
- //Geometry2D.
- // var point = new Vector2[]
- // {
- // new Vector2(0, 0),
- // new Vector2(0, 500),
- // new Vector2(500, 500),
- // new Vector2(500, 0)
- // };
- // Result = Geometry2D.ClipPolygons(point, new Vector2[]
- // {
- // new Vector2(20, 20),
- // new Vector2(20, 100),
- // new Vector2(90, 50),
- // });
- //PolygonNode.Polygon = clipPolygons[0];
- }
-
- public override void _Process(double delta)
- {
- //if (Input.IsActionJustPressed("fire"))
- if (Input.IsActionPressed("fire") || Input.IsActionJustPressed("roll"))
- {
- var time = DateTime.Now;
- RunTest();
- Debug.Log("用时: " + (DateTime.Now - time).TotalMilliseconds);
- }
-
- if (Input.IsActionJustPressed("meleeAttack"))
- {
- for (var i = 0; i < Result.Count; i++)
- {
- var temp = Result[i];
- Result[i] = StreamlineVertices3(temp, 10, Mathf.DegToRad(15));
- Debug.Log($"优化前: {temp.Length}, 优化后: {Result[i].Length}");
- }
- }
-
- if (Input.IsActionJustPressed("exchangeWeapon"))
- {
- Result.Clear();
- }
- QueueRedraw();
- }
-
- private void RunTest()
- {
- var position = GetGlobalMousePosition();
- var circle = GetCircle(position, 50, 10);
- //先检测有没有碰撞
- var flag = false;
- for (var i = 0; i < Result.Count; i++)
- {
- var p = Result[i];
- if (CollisionPolygon(p, circle))
- {
- flag = true;
- var mergePolygons = Geometry2D.MergePolygons(p, circle);
- Result.RemoveAt(i);
- for (var j = 0; j < mergePolygons.Count; j++)
- {
- Result.Add(mergePolygons[j]);
- //Result.Add(StreamlineVertices(mergePolygons[j], 50));
- //Result.Add(StreamlineVertices2(mergePolygons[j], Mathf.DegToRad(5)));
- //Result.Add(StreamlineVertices3(mergePolygons[j], 20, Mathf.DegToRad(15)));
- }
- break;
- }
- }
-
- if (!flag)
- {
- Result.Add(circle);
- //Result.Add(StreamlineVertices2(circle, Mathf.DegToRad(5)));
- }
- }
-
- private Vector2[] StreamlineVertices3(Vector2[] polygon, float d, float r)
- {
- if (polygon.Length <= 3)
- {
- return polygon;
- }
-
- float v = d * d;
- List<Vector2> list = new List<Vector2>();
- Vector2 tempPoint = polygon[0];
- Vector2 tempPoint2 = polygon[1];
- list.Add(tempPoint);
- float tr = tempPoint.AngleToPoint(tempPoint2);
- float delta = 0;
- for (var i = 1; i < polygon.Length; i++)
- {
- var curr = polygon[i];
- var prev = polygon[i > 0 ? i - 1 : polygon.Length - 1];
- var next = polygon[i < polygon.Length - 1 ? i + 1 : 0];
- if (prev.DistanceSquaredTo(next) > v)
- {
- //list.Add(curr);
-
- var angle = curr.AngleToPoint(next);
- delta += angle - tr;
- if (Mathf.Abs(delta) >= r)
- {
- Debug.Log(i + ", 偏差角度: " + Mathf.RadToDeg(delta));
- tr = angle;
- delta = 0;
- //var result = Geometry2D.GetClosestPointToSegmentUncapped(curr, tempPoint, tempPoint2);
- tempPoint = curr;
- //tempPoint2 = next;
- list.Add(tempPoint);
- }
- }
- }
-
- return list.ToArray();
- }
-
- private bool CollisionPolygon(Vector2[] polygon1, Vector2[] polygon2)
- {
- for (int shape = 0; shape < 2; shape++)
- {
- if (shape == 1)
- {
- Vector2[] tmp = polygon1;
- polygon1 = polygon2;
- polygon2 = tmp;
- }
-
- for (int a = 0; a < polygon1.Length; a++)
- {
- int b = (a + 1) % polygon1.Length;
- float axisX = -(polygon1[b].Y - polygon1[a].Y);
- float axisY = polygon1[b].X - polygon1[a].X;
-
- float mina = float.MaxValue;
- float maxa = float.MinValue;
- for (int p = 0; p < polygon1.Length; p++)
- {
- float t = polygon1[p].X * axisX + polygon1[p].Y * axisY;
- mina = Math.Min(mina, t);
- maxa = Math.Max(maxa, t);
- }
-
- float minb = float.MaxValue;
- float maxb = float.MinValue;
- for (int p = 0; p < polygon2.Length; p++)
- {
- float t = polygon2[p].X * axisX + polygon2[p].Y * axisY;
- minb = Math.Min(minb, t);
- maxb = Math.Max(maxb, t);
- }
-
- if (maxa < minb || mina > maxb)
- return false;
- }
- }
-
- return true;
- }
-
- private Vector2[] GetCircle(Vector2 position, float radius, int vertexCount)
- {
- Vector2[] vertices = new Vector2[vertexCount];
-
- for (int i = 0; i < vertexCount; i++)
- {
- float angle = i * 2.0f * (float)Math.PI / vertexCount;
- Vector2 vertex = position + new Vector2((float)Math.Cos(angle) * radius, (float)Math.Sin(angle) * radius);
- vertices[i] = vertex;
- }
-
- return vertices;
- }
-
- public override void _Draw()
- {
- if (Result != null)
- {
- foreach (var vector2s in Result)
- {
- var list = vector2s.ToList();
- list.Add(vector2s[0]);
- DrawPolyline(list.ToArray(), Colors.Red);
- foreach (var vector2 in list)
- {
- DrawCircle(vector2, 2, Colors.Green);
- }
- }
- //DrawColoredPolygon(Result[1], Colors.Red);
- }
-
- }
- }