NLDClient-yudde/ProjectNLD/Assets/ThirdParty/TerrainGridSystem/Scripts/Geom/PolygonClipping/SweepEventSet.cs

87 lines
2.3 KiB
C#
Raw Normal View History

2023-08-22 19:08:45 +08:00
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace TGS.Geom {
class SweepEventSet {
public List<SweepEvent>eventSet;
public SweepEventSet () {
eventSet = new List<SweepEvent> (1000);
}
public void Remove (SweepEvent key) {
int keyIndex = eventSet.IndexOf (key);
if (keyIndex == -1)
return;
eventSet.RemoveAt (keyIndex);
}
public int Insert (SweepEvent item) {
int count = eventSet.Count;
if (count == 0) {
eventSet.Add (item);
return 0;
}
eventSet.Add (null); // Expand the Vector by one.
int i = count - 1;
while (i >= 0 && SegmentCompare(item, eventSet[i])) {
eventSet [i + 1] = eventSet [i];
i--;
}
eventSet [i + 1] = item;
return i + 1;
}
double signedArea (Point p0, Point p1, Point p2) {
return (p0.x - p2.x) * (p1.y - p2.y) - (p1.x - p2.x) * (p0.y - p2.y);
}
private bool SegmentCompare (SweepEvent e1, SweepEvent e2) {
if (e1.Equals(e2))
return false;
if (signedArea (e1.p, e1.otherSE.p, e2.p) != 0 || signedArea (e1.p, e1.otherSE.p, e2.otherSE.p) != 0) {
// Segments are not collinear
// If they share their left endpoint use the right endpoint to sort
if (Point.EqualsBoth(e1.p, e2.p))
return e1.isBelow (e2.otherSE.p);
if (CompareSweepEvent (e1, e2))
return e2.isAbove (e1.p);
return e1.isBelow (e2.p);
}
if (Point.EqualsBoth(e1.p, e2.p)) // Segments colinear
return false;
return CompareSweepEvent (e1, e2);
}
// Should only be called by segmentCompare
private bool CompareSweepEvent (SweepEvent e1, SweepEvent e2) {
if (e1.p.x > e2.p.x) // Different x coordinate
return true;
if (e2.p.x > e1.p.x) // Different x coordinate
return false;
if (e1.p != e2.p) // Different points, but same x coordinate. The event with lower y coordinate is processed first
return e1.p.y > e2.p.y;
if (e1.isLeft != e2.isLeft) // Same point, but one is a left endpoint and the other a right endpoint. The right endpoint is processed first
return e1.isLeft;
// Same point, both events are left endpoints or both are right endpoints. The event associate to the bottom segment is processed first
return e1.isAbove (e2.otherSE.p);
}
}
}