Decompiled source of TerraMesh v1.1.1
voxx.TerraMesh.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using TerraMesh.Utils; using TriangleNet.Geometry; using TriangleNet.IO; using TriangleNet.Logging; using TriangleNet.Meshing; using TriangleNet.Meshing.Algorithm; using TriangleNet.Meshing.Data; using TriangleNet.Meshing.Iterators; using TriangleNet.Smoothing; using TriangleNet.Tools; using TriangleNet.Topology; using TriangleNet.Topology.DCEL; using TriangleNet.Unity; using TriangleNet.Voronoi; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("TerraMesh")] [assembly: AssemblyDescription("Triangle.Net based library for modifying mesh and terrain objects in Unity")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("voxx")] [assembly: AssemblyProduct("TerraMesh")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("96a130d0-1772-4bed-8d25-ef5fa23cd1bc")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace TriangleNet { internal class Behavior { private bool poly; private bool quality; private bool varArea; private bool convex; private bool jettison; private bool boundaryMarkers = true; private bool noHoles; private bool conformDel; private Func<ITriangle, float, bool> usertest; private int noBisect; private float minAngle; private float maxAngle; private float maxArea = -1f; internal bool fixedArea; internal bool useSegments = true; internal bool useRegions; internal float goodAngle; internal float maxGoodAngle; internal float offconstant; public static bool NoExact { get; set; } public bool Quality { get { return quality; } set { quality = value; if (quality) { Update(); } } } public float MinAngle { get { return minAngle; } set { minAngle = value; Update(); } } public float MaxAngle { get { return maxAngle; } set { maxAngle = value; Update(); } } public float MaxArea { get { return maxArea; } set { maxArea = value; fixedArea = value > 0f; } } public bool VarArea { get { return varArea; } set { varArea = value; } } public bool Poly { get { return poly; } set { poly = value; } } public Func<ITriangle, float, bool> UserTest { get { return usertest; } set { usertest = value; } } public bool Convex { get { return convex; } set { convex = value; } } public bool ConformingDelaunay { get { return conformDel; } set { conformDel = value; } } public int NoBisect { get { return noBisect; } set { noBisect = value; if (noBisect < 0 || noBisect > 2) { noBisect = 0; } } } public bool UseBoundaryMarkers { get { return boundaryMarkers; } set { boundaryMarkers = value; } } public bool NoHoles { get { return noHoles; } set { noHoles = value; } } public bool Jettison { get { return jettison; } set { jettison = value; } } public Behavior(bool quality = false, float minAngle = 20f) { if (quality) { this.quality = true; this.minAngle = minAngle; Update(); } } private void Update() { quality = true; if (minAngle < 0f || minAngle > 60f) { minAngle = 0f; quality = false; Log.Instance.Warning("Invalid quality option (minimum angle).", "Mesh.Behavior"); } if ((double)maxAngle != 0.0 && (maxAngle < 60f || maxAngle > 180f)) { maxAngle = 0f; quality = false; Log.Instance.Warning("Invalid quality option (maximum angle).", "Mesh.Behavior"); } useSegments = Poly || Quality || Convex; goodAngle = Mathf.Cos(MinAngle * MathF.PI / 180f); maxGoodAngle = Mathf.Cos(MaxAngle * MathF.PI / 180f); if (goodAngle == 1f) { offconstant = 0f; } else { offconstant = 0.475f * Mathf.Sqrt((1f + goodAngle) / (1f - goodAngle)); } goodAngle *= goodAngle; } } public class Configuration { public Func<IPredicates> Predicates { get; set; } public Func<TrianglePool> TrianglePool { get; set; } public Configuration() : this(() => RobustPredicates.Default, () => new TrianglePool()) { } public Configuration(Func<IPredicates> predicates) : this(predicates, () => new TrianglePool()) { } public Configuration(Func<IPredicates> predicates, Func<TrianglePool> trianglePool) { Predicates = predicates; TrianglePool = trianglePool; } } public enum VertexType { InputVertex, SegmentVertex, FreeVertex, DeadVertex, UndeadVertex } public enum NodeNumbering { None, Linear, CuthillMcKee } public enum LocateResult { InTriangle, OnEdge, OnVertex, Outside } internal enum InsertVertexResult { Successful, Encroaching, Violating, Duplicate } internal enum FindDirectionResult { Within, Leftcollinear, Rightcollinear } public interface IPredicates { float CounterClockwise(Point a, Point b, Point c); float InCircle(Point a, Point b, Point c, Point p); Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta); Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta, float offconstant); } public sealed class Log : ILog<LogItem> { private List<LogItem> log = new List<LogItem>(); private LogLevel level; private static readonly Log instance; public static bool Verbose { get; set; } public static ILog<LogItem> Instance => instance; public IList<LogItem> Data => log; public LogLevel Level => level; static Log() { instance = new Log(); } private Log() { } public void Add(LogItem item) { log.Add(item); } public void Clear() { log.Clear(); } public void Info(string message) { log.Add(new LogItem(LogLevel.Info, message)); } public void Warning(string message, string location) { log.Add(new LogItem(LogLevel.Warning, message, location)); } public void Error(string message, string location) { log.Add(new LogItem(LogLevel.Error, message, location)); } } public static class MeshValidator { private static RobustPredicates predicates = RobustPredicates.Default; public static bool IsConsistent(TriangleNetMesh triangleNetMesh) { Otri otri = default(Otri); Otri ot = default(Otri); Otri ot2 = default(Otri); ILog<LogItem> instance = Log.Instance; bool noExact = Behavior.NoExact; Behavior.NoExact = false; int num = 0; foreach (Triangle triangle2 in triangleNetMesh.triangles) { Triangle triangle = (otri.tri = triangle2); otri.orient = 0; while (otri.orient < 3) { TriangleNet.Geometry.Vertex vertex = otri.Org(); TriangleNet.Geometry.Vertex vertex2 = otri.Dest(); if (otri.orient == 0) { TriangleNet.Geometry.Vertex pc = otri.Apex(); if ((double)predicates.CounterClockwise(vertex, vertex2, pc) <= 0.0) { if (Log.Verbose) { instance.Warning($"Triangle is flat or inverted (ID {triangle.id}).", "MeshValidator.IsConsistent()"); } num++; } } otri.Sym(ref ot); if (ot.tri.id != -1) { ot.Sym(ref ot2); if (otri.tri != ot2.tri || otri.orient != ot2.orient) { if (otri.tri == ot2.tri && Log.Verbose) { instance.Warning("Asymmetric triangle-triangle bond: (Right triangle, wrong orientation)", "MeshValidator.IsConsistent()"); } num++; } TriangleNet.Geometry.Vertex vertex3 = ot.Org(); TriangleNet.Geometry.Vertex vertex4 = ot.Dest(); if (vertex != vertex4 || vertex2 != vertex3) { if (Log.Verbose) { instance.Warning("Mismatched edge coordinates between two triangles.", "MeshValidator.IsConsistent()"); } num++; } } otri.orient++; } } triangleNetMesh.MakeVertexMap(); foreach (TriangleNet.Geometry.Vertex value in triangleNetMesh.vertices.Values) { if (value.tri.tri == null && Log.Verbose) { instance.Warning("Vertex (ID " + value.id + ") not connected to mesh (duplicate input vertex?)", "MeshValidator.IsConsistent()"); } } Behavior.NoExact = noExact; return num == 0; } public static bool IsDelaunay(TriangleNetMesh triangleNetMesh) { return IsDelaunay(triangleNetMesh, constrained: false); } public static bool IsConstrainedDelaunay(TriangleNetMesh triangleNetMesh) { return IsDelaunay(triangleNetMesh, constrained: true); } private static bool IsDelaunay(TriangleNetMesh triangleNetMesh, bool constrained) { Otri otri = default(Otri); Otri ot = default(Otri); Osub os = default(Osub); ILog<LogItem> instance = Log.Instance; bool noExact = Behavior.NoExact; Behavior.NoExact = false; int num = 0; TriangleNet.Geometry.Vertex infvertex = triangleNetMesh.infvertex1; TriangleNet.Geometry.Vertex infvertex2 = triangleNetMesh.infvertex2; TriangleNet.Geometry.Vertex infvertex3 = triangleNetMesh.infvertex3; foreach (Triangle triangle in triangleNetMesh.triangles) { otri.tri = triangle; otri.orient = 0; while (otri.orient < 3) { TriangleNet.Geometry.Vertex vertex = otri.Org(); TriangleNet.Geometry.Vertex vertex2 = otri.Dest(); TriangleNet.Geometry.Vertex vertex3 = otri.Apex(); otri.Sym(ref ot); TriangleNet.Geometry.Vertex vertex4 = ot.Apex(); bool flag = otri.tri.id < ot.tri.id && !Otri.IsDead(ot.tri) && ot.tri.id != -1 && vertex != infvertex && vertex != infvertex2 && vertex != infvertex3 && vertex2 != infvertex && vertex2 != infvertex2 && vertex2 != infvertex3 && vertex3 != infvertex && vertex3 != infvertex2 && vertex3 != infvertex3 && vertex4 != infvertex && vertex4 != infvertex2 && vertex4 != infvertex3; if (constrained && triangleNetMesh.checksegments && flag) { otri.Pivot(ref os); if (os.seg.hash != -1) { flag = false; } } if (flag && (double)predicates.NonRegular(vertex, vertex2, vertex3, vertex4) > 0.0) { if (Log.Verbose) { instance.Warning($"Non-regular pair of triangles found (IDs {otri.tri.id}/{ot.tri.id}).", "MeshValidator.IsDelaunay()"); } num++; } otri.orient++; } } Behavior.NoExact = noExact; return num == 0; } } internal class NewLocation { private const float EPS = 0f; private IPredicates predicates; private TriangleNetMesh _TriangleNetMesh; private Behavior behavior; private float[] petalx = new float[20]; private float[] petaly = new float[20]; private float[] petalr = new float[20]; private float[] wedges = new float[500]; private float[] initialConvexPoly = new float[500]; private float[] points_p = new float[500]; private float[] points_q = new float[500]; private float[] points_r = new float[500]; private float[] poly1 = new float[100]; private float[] poly2 = new float[100]; private float[][] polys = new float[3][]; public NewLocation(TriangleNetMesh triangleNetMesh, IPredicates predicates) { _TriangleNetMesh = triangleNetMesh; this.predicates = predicates; behavior = triangleNetMesh.behavior; } public Point FindLocation(TriangleNet.Geometry.Vertex org, TriangleNet.Geometry.Vertex dest, TriangleNet.Geometry.Vertex apex, ref float xi, ref float eta, bool offcenter, Otri badotri) { if (behavior.MaxAngle == 0f) { return FindNewLocationWithoutMaxAngle(org, dest, apex, ref xi, ref eta, offcenter: true, badotri); } return FindNewLocation(org, dest, apex, ref xi, ref eta, offcenter: true, badotri); } private Point FindNewLocationWithoutMaxAngle(TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float xi, ref float eta, bool offcenter, Otri badotri) { float offconstant = behavior.offconstant; float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; int num6 = 0; int num7 = 0; Otri neighotri = default(Otri); float[] thirdpoint = new float[2]; float xi2 = 0f; float eta2 = 0f; float[] p = new float[5]; float[] p2 = new float[4]; float num8 = 0.06f; float num9 = 1f; float num10 = 1f; int num11 = 0; float[] newloc = new float[2]; float num12 = 0f; float num13 = 0f; Statistic.CircumcenterCount++; float num14 = tdest.x - torg.x; float num15 = tdest.y - torg.y; float num16 = tapex.x - torg.x; float num17 = tapex.y - torg.y; float num18 = tapex.x - tdest.x; float num19 = tapex.y - tdest.y; float num20 = num14 * num14 + num15 * num15; float num21 = num16 * num16 + num17 * num17; float num22 = (tdest.x - tapex.x) * (tdest.x - tapex.x) + (tdest.y - tapex.y) * (tdest.y - tapex.y); float num23; if (Behavior.NoExact) { num23 = 0.5f / (num14 * num17 - num16 * num15); } else { num23 = 0.5f / predicates.CounterClockwise(tdest, tapex, torg); Statistic.CounterClockwiseCount--; } float num24 = (num17 * num20 - num15 * num21) * num23; float num25 = (num14 * num21 - num16 * num20) * num23; Point point = new Point(torg.x + num24, torg.y + num25); Otri deltri = badotri; num6 = LongestShortestEdge(num21, num22, num20); Point point2; Point point3; Point point4; switch (num6) { case 123: num = num16; num2 = num17; num3 = num21; num4 = num22; num5 = num20; point2 = tdest; point3 = torg; point4 = tapex; break; case 132: num = num16; num2 = num17; num3 = num21; num4 = num20; num5 = num22; point2 = tdest; point3 = tapex; point4 = torg; break; case 213: num = num18; num2 = num19; num3 = num22; num4 = num21; num5 = num20; point2 = torg; point3 = tdest; point4 = tapex; break; case 231: num = num18; num2 = num19; num3 = num22; num4 = num20; num5 = num21; point2 = torg; point3 = tapex; point4 = tdest; break; case 312: num = num14; num2 = num15; num3 = num20; num4 = num21; num5 = num22; point2 = tapex; point3 = tdest; point4 = torg; break; default: num = num14; num2 = num15; num3 = num20; num4 = num22; num5 = num21; point2 = tapex; point3 = torg; point4 = tdest; break; } if (offcenter && offconstant > 0f) { switch (num6) { case 213: case 231: { float num26 = 0.5f * num - offconstant * num2; float num27 = 0.5f * num2 + offconstant * num; if (num26 * num26 + num27 * num27 < (num24 - num14) * (num24 - num14) + (num25 - num15) * (num25 - num15)) { num24 = num14 + num26; num25 = num15 + num27; } else { num7 = 1; } break; } case 123: case 132: { float num26 = 0.5f * num + offconstant * num2; float num27 = 0.5f * num2 - offconstant * num; if (num26 * num26 + num27 * num27 < num24 * num24 + num25 * num25) { num24 = num26; num25 = num27; } else { num7 = 1; } break; } default: { float num26 = 0.5f * num - offconstant * num2; float num27 = 0.5f * num2 + offconstant * num; if (num26 * num26 + num27 * num27 < num24 * num24 + num25 * num25) { num24 = num26; num25 = num27; } else { num7 = 1; } break; } } } if (num7 == 1) { float num28 = (num4 + num3 - num5) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num3)); bool flag = num28 < 0f || Mathf.Abs(num28 - 0f) <= 0f; num11 = DoSmoothing(deltri, torg, tdest, tapex, ref newloc); if (num11 > 0) { Statistic.RelocationCount++; num24 = newloc[0] - torg.x; num25 = newloc[1] - torg.y; num12 = torg.x; num13 = torg.y; switch (num11) { case 1: _TriangleNetMesh.DeleteVertex(ref deltri); break; case 2: deltri.Lnext(); _TriangleNetMesh.DeleteVertex(ref deltri); break; case 3: deltri.Lprev(); _TriangleNetMesh.DeleteVertex(ref deltri); break; } } else { float num29 = Mathf.Sqrt(num3) / (2f * Mathf.Sin(behavior.MinAngle * MathF.PI / 180f)); float num30 = (point3.x + point4.x) / 2f; float num31 = (point3.y + point4.y) / 2f; float num32 = num30 + Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3); float num33 = num31 + Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3); float num34 = num30 - Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3); float num35 = num31 - Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3); float num36 = (num32 - point2.x) * (num32 - point2.x); float num37 = (num33 - point2.y) * (num33 - point2.y); float num38 = (num34 - point2.x) * (num34 - point2.x); float num39 = (num35 - point2.y) * (num35 - point2.y); float x; float y; if (num36 + num37 <= num38 + num39) { x = num32; y = num33; } else { x = num34; y = num35; } bool neighborsVertex = GetNeighborsVertex(badotri, point3.x, point3.y, point2.x, point2.y, ref thirdpoint, ref neighotri); float num40 = num24; float num41 = num25; if (!neighborsVertex) { TriangleNet.Geometry.Vertex org = neighotri.Org(); TriangleNet.Geometry.Vertex dest = neighotri.Dest(); TriangleNet.Geometry.Vertex apex = neighotri.Apex(); Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2); float num42 = point3.y - point2.y; float num43 = point2.x - point3.x; num42 = point.x + num42; num43 = point.y + num43; CircleLineIntersection(point.x, point.y, num42, num43, x, y, num29, ref p); float x2 = (point3.x + point2.x) / 2f; float y2 = (point3.y + point2.y) / 2f; float num44; float num45; if (ChooseCorrectPoint(x2, y2, p[3], p[4], point.x, point.y, flag)) { num44 = p[3]; num45 = p[4]; } else { num44 = p[1]; num45 = p[2]; } PointBetweenPoints(num44, num45, point.x, point.y, point5.x, point5.y, ref p2); if ((double)p[0] > 0.0) { if (Mathf.Abs(p2[0] - 1f) <= 0f) { if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y)) { num40 = num24; num41 = num25; } else { num40 = p2[2] - torg.x; num41 = p2[3] - torg.y; } } else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num44, num45)) { float num46 = Mathf.Sqrt((num44 - point.x) * (num44 - point.x) + (num45 - point.y) * (num45 - point.y)); float num47 = point.x - num44; float num48 = point.y - num45; num47 /= num46; num48 /= num46; num44 += num47 * num8 * Mathf.Sqrt(num3); num45 += num48 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45)) { num40 = num24; num41 = num25; } else { num40 = num44 - torg.x; num41 = num45 - torg.y; } } else { num40 = num44 - torg.x; num41 = num45 - torg.y; } if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num40 + torg.x)) * (point2.x - (num40 + torg.x)) + (point2.y - (num41 + torg.y)) * (point2.y - (num41 + torg.y)))) { num40 = num24; num41 = num25; } } } neighborsVertex = GetNeighborsVertex(badotri, point4.x, point4.y, point2.x, point2.y, ref thirdpoint, ref neighotri); float num49 = num24; float num50 = num25; if (!neighborsVertex) { TriangleNet.Geometry.Vertex org = neighotri.Org(); TriangleNet.Geometry.Vertex dest = neighotri.Dest(); TriangleNet.Geometry.Vertex apex = neighotri.Apex(); Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2); float num42 = point4.y - point2.y; float num43 = point2.x - point4.x; num42 = point.x + num42; num43 = point.y + num43; CircleLineIntersection(point.x, point.y, num42, num43, x, y, num29, ref p); float x3 = (point4.x + point2.x) / 2f; float y3 = (point4.y + point2.y) / 2f; float num44; float num45; if (ChooseCorrectPoint(x3, y3, p[3], p[4], point.x, point.y, isObtuse: false)) { num44 = p[3]; num45 = p[4]; } else { num44 = p[1]; num45 = p[2]; } PointBetweenPoints(num44, num45, point.x, point.y, point5.x, point5.y, ref p2); if (p[0] > 0f) { if (Mathf.Abs(p2[0] - 1f) <= 0f) { if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y)) { num49 = num24; num50 = num25; } else { num49 = p2[2] - torg.x; num50 = p2[3] - torg.y; } } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45)) { float num46 = Mathf.Sqrt((num44 - point.x) * (num44 - point.x) + (num45 - point.y) * (num45 - point.y)); float num47 = point.x - num44; float num48 = point.y - num45; num47 /= num46; num48 /= num46; num44 += num47 * num8 * Mathf.Sqrt(num3); num45 += num48 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45)) { num49 = num24; num50 = num25; } else { num49 = num44 - torg.x; num50 = num45 - torg.y; } } else { num49 = num44 - torg.x; num50 = num45 - torg.y; } if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num49 + torg.x)) * (point2.x - (num49 + torg.x)) + (point2.y - (num50 + torg.y)) * (point2.y - (num50 + torg.y)))) { num49 = num24; num50 = num25; } } } if (flag) { num24 = num40; num25 = num41; } else if (num10 * ((point2.x - (num49 + torg.x)) * (point2.x - (num49 + torg.x)) + (point2.y - (num50 + torg.y)) * (point2.y - (num50 + torg.y))) > (point2.x - (num40 + torg.x)) * (point2.x - (num40 + torg.x)) + (point2.y - (num41 + torg.y)) * (point2.y - (num41 + torg.y))) { num24 = num49; num25 = num50; } else { num24 = num40; num25 = num41; } } } Point point6 = new Point(); if (num11 <= 0) { point6.x = torg.x + num24; point6.y = torg.y + num25; } else { point6.x = num12 + num24; point6.y = num13 + num25; } xi = (num17 * num24 - num16 * num25) * (2f * num23); eta = (num14 * num25 - num15 * num24) * (2f * num23); return point6; } private Point FindNewLocation(TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float xi, ref float eta, bool offcenter, Otri badotri) { float offconstant = behavior.offconstant; float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; int num6 = 0; int num7 = 0; Otri neighotri = default(Otri); float[] thirdpoint = new float[2]; float xi2 = 0f; float eta2 = 0f; float[] p = new float[5]; float[] p2 = new float[4]; float num8 = 0.06f; float num9 = 1f; float num10 = 1f; int num11 = 0; float[] newloc = new float[2]; float num12 = 0f; float num13 = 0f; float num14 = 0f; float num15 = 0f; float[] p3 = new float[3]; float[] p4 = new float[4]; Statistic.CircumcenterCount++; float num16 = tdest.x - torg.x; float num17 = tdest.y - torg.y; float num18 = tapex.x - torg.x; float num19 = tapex.y - torg.y; float num20 = tapex.x - tdest.x; float num21 = tapex.y - tdest.y; float num22 = num16 * num16 + num17 * num17; float num23 = num18 * num18 + num19 * num19; float num24 = (tdest.x - tapex.x) * (tdest.x - tapex.x) + (tdest.y - tapex.y) * (tdest.y - tapex.y); float num25; if (Behavior.NoExact) { num25 = 0.5f / (num16 * num19 - num18 * num17); } else { num25 = 0.5f / predicates.CounterClockwise(tdest, tapex, torg); Statistic.CounterClockwiseCount--; } float num26 = (num19 * num22 - num17 * num23) * num25; float num27 = (num16 * num23 - num18 * num22) * num25; Point point = new Point(torg.x + num26, torg.y + num27); Otri deltri = badotri; num6 = LongestShortestEdge(num23, num24, num22); Point point2; Point point3; Point point4; switch (num6) { case 123: num = num18; num2 = num19; num3 = num23; num4 = num24; num5 = num22; point2 = tdest; point3 = torg; point4 = tapex; break; case 132: num = num18; num2 = num19; num3 = num23; num4 = num22; num5 = num24; point2 = tdest; point3 = tapex; point4 = torg; break; case 213: num = num20; num2 = num21; num3 = num24; num4 = num23; num5 = num22; point2 = torg; point3 = tdest; point4 = tapex; break; case 231: num = num20; num2 = num21; num3 = num24; num4 = num22; num5 = num23; point2 = torg; point3 = tapex; point4 = tdest; break; case 312: num = num16; num2 = num17; num3 = num22; num4 = num23; num5 = num24; point2 = tapex; point3 = tdest; point4 = torg; break; default: num = num16; num2 = num17; num3 = num22; num4 = num24; num5 = num23; point2 = tapex; point3 = torg; point4 = tdest; break; } if (offcenter && offconstant > 0f) { switch (num6) { case 213: case 231: { float num28 = 0.5f * num - offconstant * num2; float num29 = 0.5f * num2 + offconstant * num; if (num28 * num28 + num29 * num29 < (num26 - num16) * (num26 - num16) + (num27 - num17) * (num27 - num17)) { num26 = num16 + num28; num27 = num17 + num29; } else { num7 = 1; } break; } case 123: case 132: { float num28 = 0.5f * num + offconstant * num2; float num29 = 0.5f * num2 - offconstant * num; if (num28 * num28 + num29 * num29 < num26 * num26 + num27 * num27) { num26 = num28; num27 = num29; } else { num7 = 1; } break; } default: { float num28 = 0.5f * num - offconstant * num2; float num29 = 0.5f * num2 + offconstant * num; if (num28 * num28 + num29 * num29 < num26 * num26 + num27 * num27) { num26 = num28; num27 = num29; } else { num7 = 1; } break; } } } if (num7 == 1) { float num30 = (num4 + num3 - num5) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num3)); bool flag = num30 < 0f || Mathf.Abs(num30 - 0f) <= 0f; num11 = DoSmoothing(deltri, torg, tdest, tapex, ref newloc); if (num11 > 0) { Statistic.RelocationCount++; num26 = newloc[0] - torg.x; num27 = newloc[1] - torg.y; num12 = torg.x; num13 = torg.y; switch (num11) { case 1: _TriangleNetMesh.DeleteVertex(ref deltri); break; case 2: deltri.Lnext(); _TriangleNetMesh.DeleteVertex(ref deltri); break; case 3: deltri.Lprev(); _TriangleNetMesh.DeleteVertex(ref deltri); break; } } else { float num31 = Mathf.Acos((num4 + num5 - num3) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num5))) * 180f / MathF.PI; num31 = ((!(behavior.MinAngle > num31)) ? (num31 + 0.5f) : behavior.MinAngle); float num32 = Mathf.Sqrt(num3) / (2f * Mathf.Sin(num31 * MathF.PI / 180f)); float num33 = (point3.x + point4.x) / 2f; float num34 = (point3.y + point4.y) / 2f; float num35 = num33 + Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3); float num36 = num34 + Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3); float num37 = num33 - Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3); float num38 = num34 - Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3); float num39 = (num35 - point2.x) * (num35 - point2.x); float num40 = (num36 - point2.y) * (num36 - point2.y); float num41 = (num37 - point2.x) * (num37 - point2.x); float num42 = (num38 - point2.y) * (num38 - point2.y); float num43; float num44; if (num39 + num40 <= num41 + num42) { num43 = num35; num44 = num36; } else { num43 = num37; num44 = num38; } bool neighborsVertex = GetNeighborsVertex(badotri, point3.x, point3.y, point2.x, point2.y, ref thirdpoint, ref neighotri); float num45 = num26; float num46 = num27; float num47 = Mathf.Sqrt((num43 - num33) * (num43 - num33) + (num44 - num34) * (num44 - num34)); float num48 = (num43 - num33) / num47; float num49 = (num44 - num34) / num47; float num50 = num43 + num48 * num32; float num51 = num44 + num49 * num32; float num52 = (2f * behavior.MaxAngle + num31 - 180f) * MathF.PI / 180f; float num53 = num50 * Mathf.Cos(num52) + num51 * Mathf.Sin(num52) + num43 - num43 * Mathf.Cos(num52) - num44 * Mathf.Sin(num52); float num54 = (0f - num50) * Mathf.Sin(num52) + num51 * Mathf.Cos(num52) + num44 + num43 * Mathf.Sin(num52) - num44 * Mathf.Cos(num52); float num55 = num50 * Mathf.Cos(num52) - num51 * Mathf.Sin(num52) + num43 - num43 * Mathf.Cos(num52) + num44 * Mathf.Sin(num52); float num56 = num50 * Mathf.Sin(num52) + num51 * Mathf.Cos(num52) + num44 - num43 * Mathf.Sin(num52) - num44 * Mathf.Cos(num52); float num57; float num58; float num59; float num60; if (ChooseCorrectPoint(num55, num56, point3.x, point3.y, num53, num54, isObtuse: true)) { num57 = num53; num58 = num54; num59 = num55; num60 = num56; } else { num57 = num55; num58 = num56; num59 = num53; num60 = num54; } float num61 = (point3.x + point2.x) / 2f; float num62 = (point3.y + point2.y) / 2f; if (!neighborsVertex) { TriangleNet.Geometry.Vertex org = neighotri.Org(); TriangleNet.Geometry.Vertex dest = neighotri.Dest(); TriangleNet.Geometry.Vertex apex = neighotri.Apex(); Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2); float num63 = point3.y - point2.y; float num64 = point2.x - point3.x; num63 = point.x + num63; num64 = point.y + num64; CircleLineIntersection(point.x, point.y, num63, num64, num43, num44, num32, ref p); float num65; float num66; if (ChooseCorrectPoint(num61, num62, p[3], p[4], point.x, point.y, flag)) { num65 = p[3]; num66 = p[4]; } else { num65 = p[1]; num66 = p[2]; } float x = point3.x; float y = point3.y; num48 = point4.x - point3.x; num49 = point4.y - point3.y; float x2 = num57; float y2 = num58; LineLineIntersection(point.x, point.y, num63, num64, x, y, x2, y2, ref p3); if (p3[0] > 0f) { num14 = p3[1]; num15 = p3[2]; } PointBetweenPoints(num65, num66, point.x, point.y, point5.x, point5.y, ref p2); if (p[0] > 0f) { if (Mathf.Abs(p2[0] - 1f) <= 0f) { PointBetweenPoints(p2[2], p2[3], point.x, point.y, num14, num15, ref p4); if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0) { if ((point2.x - num57) * (point2.x - num57) + (point2.y - num58) * (point2.y - num58) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num57, num58) && MinDistanceToNeighbor(num57, num58, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri)) { num45 = num57 - torg.x; num46 = num58 - torg.y; } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y)); float num68 = point.x - num14; float num69 = point.y - num15; num68 /= num67; num69 /= num67; num14 += num68 * num8 * Mathf.Sqrt(num3); num15 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { num45 = num26; num46 = num27; } else { num45 = num14 - torg.x; num46 = num15 - torg.y; } } else { num45 = p4[2] - torg.x; num46 = p4[3] - torg.y; } } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y)) { num45 = num26; num46 = num27; } else { num45 = p2[2] - torg.x; num46 = p2[3] - torg.y; } } else { PointBetweenPoints(num65, num66, point.x, point.y, num14, num15, ref p4); if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0) { if ((point2.x - num57) * (point2.x - num57) + (point2.y - num58) * (point2.y - num58) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num57, num58) && MinDistanceToNeighbor(num57, num58, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri)) { num45 = num57 - torg.x; num46 = num58 - torg.y; } else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num14, num15)) { float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y)); float num68 = point.x - num14; float num69 = point.y - num15; num68 /= num67; num69 /= num67; num14 += num68 * num8 * Mathf.Sqrt(num3); num15 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { num45 = num26; num46 = num27; } else { num45 = num14 - torg.x; num46 = num15 - torg.y; } } else { num45 = p4[2] - torg.x; num46 = p4[3] - torg.y; } } else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num65, num66)) { float num67 = Mathf.Sqrt((num65 - point.x) * (num65 - point.x) + (num66 - point.y) * (num66 - point.y)); float num68 = point.x - num65; float num69 = point.y - num66; num68 /= num67; num69 /= num67; num65 += num68 * num8 * Mathf.Sqrt(num3); num66 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66)) { num45 = num26; num46 = num27; } else { num45 = num65 - torg.x; num46 = num66 - torg.y; } } else { num45 = num65 - torg.x; num46 = num66 - torg.y; } } if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y)))) { num45 = num26; num46 = num27; } } } bool neighborsVertex2 = GetNeighborsVertex(badotri, point4.x, point4.y, point2.x, point2.y, ref thirdpoint, ref neighotri); float num70 = num26; float num71 = num27; float num72 = (point4.x + point2.x) / 2f; float num73 = (point4.y + point2.y) / 2f; if (!neighborsVertex2) { TriangleNet.Geometry.Vertex org = neighotri.Org(); TriangleNet.Geometry.Vertex dest = neighotri.Dest(); TriangleNet.Geometry.Vertex apex = neighotri.Apex(); Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2); float num63 = point4.y - point2.y; float num64 = point2.x - point4.x; num63 = point.x + num63; num64 = point.y + num64; CircleLineIntersection(point.x, point.y, num63, num64, num43, num44, num32, ref p); float num65; float num66; if (ChooseCorrectPoint(num72, num73, p[3], p[4], point.x, point.y, isObtuse: false)) { num65 = p[3]; num66 = p[4]; } else { num65 = p[1]; num66 = p[2]; } float x = point4.x; float y = point4.y; num48 = point3.x - point4.x; num49 = point3.y - point4.y; float x2 = num59; float y2 = num60; LineLineIntersection(point.x, point.y, num63, num64, x, y, x2, y2, ref p3); if (p3[0] > 0f) { num14 = p3[1]; num15 = p3[2]; } PointBetweenPoints(num65, num66, point.x, point.y, point5.x, point5.y, ref p2); if (p[0] > 0f) { if (Mathf.Abs(p2[0] - 1f) <= 0f) { PointBetweenPoints(p2[2], p2[3], point.x, point.y, num14, num15, ref p4); if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0) { if ((point2.x - num59) * (point2.x - num59) + (point2.y - num60) * (point2.y - num60) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num59, num60) && MinDistanceToNeighbor(num59, num60, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri)) { num70 = num59 - torg.x; num71 = num60 - torg.y; } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y)); float num68 = point.x - num14; float num69 = point.y - num15; num68 /= num67; num69 /= num67; num14 += num68 * num8 * Mathf.Sqrt(num3); num15 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { num70 = num26; num71 = num27; } else { num70 = num14 - torg.x; num71 = num15 - torg.y; } } else { num70 = p4[2] - torg.x; num71 = p4[3] - torg.y; } } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y)) { num70 = num26; num71 = num27; } else { num70 = p2[2] - torg.x; num71 = p2[3] - torg.y; } } else { PointBetweenPoints(num65, num66, point.x, point.y, num14, num15, ref p4); if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0) { if ((point2.x - num59) * (point2.x - num59) + (point2.y - num60) * (point2.y - num60) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num59, num60) && MinDistanceToNeighbor(num59, num60, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri)) { num70 = num59 - torg.x; num71 = num60 - torg.y; } else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num14, num15)) { float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y)); float num68 = point.x - num14; float num69 = point.y - num15; num68 /= num67; num69 /= num67; num14 += num68 * num8 * Mathf.Sqrt(num3); num15 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15)) { num70 = num26; num71 = num27; } else { num70 = num14 - torg.x; num71 = num15 - torg.y; } } else { num70 = p4[2] - torg.x; num71 = p4[3] - torg.y; } } else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66)) { float num67 = Mathf.Sqrt((num65 - point.x) * (num65 - point.x) + (num66 - point.y) * (num66 - point.y)); float num68 = point.x - num65; float num69 = point.y - num66; num68 /= num67; num69 /= num67; num65 += num68 * num8 * Mathf.Sqrt(num3); num66 += num69 * num8 * Mathf.Sqrt(num3); if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66)) { num70 = num26; num71 = num27; } else { num70 = num65 - torg.x; num71 = num66 - torg.y; } } else { num70 = num65 - torg.x; num71 = num66 - torg.y; } } if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y)))) { num70 = num26; num71 = num27; } } } if (flag) { if (neighborsVertex && neighborsVertex2) { if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62)) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (neighborsVertex) { if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62)) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (neighborsVertex2) { if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y))) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y))) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (neighborsVertex && neighborsVertex2) { if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62)) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (neighborsVertex) { if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62)) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (neighborsVertex2) { if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y))) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } else if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y))) { num26 = num70; num27 = num71; } else { num26 = num45; num27 = num46; } } } Point point6 = new Point(); if (num11 <= 0) { point6.x = torg.x + num26; point6.y = torg.y + num27; } else { point6.x = num12 + num26; point6.y = num13 + num27; } xi = (num19 * num26 - num18 * num27) * (2f * num25); eta = (num16 * num27 - num17 * num26) * (2f * num25); return point6; } private int LongestShortestEdge(float aodist, float dadist, float dodist) { int num = 0; int num2 = 0; int num3 = 0; if (dodist < aodist && dodist < dadist) { num2 = 3; if (aodist < dadist) { num = 2; num3 = 1; } else { num = 1; num3 = 2; } } else if (aodist < dadist) { num2 = 1; if (dodist < dadist) { num = 2; num3 = 3; } else { num = 3; num3 = 2; } } else { num2 = 2; if (aodist < dodist) { num = 3; num3 = 1; } else { num = 1; num3 = 3; } } return num2 * 100 + num3 * 10 + num; } private int DoSmoothing(Otri badotri, TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float[] newloc) { int num = 0; int num2 = 0; int num3 = 0; float[] array = new float[6]; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; bool flag = false; num = GetStarPoints(badotri, torg, tdest, tapex, 1, ref points_p); if (torg.type == VertexType.FreeVertex && num != 0 && ValidPolygonAngles(num, points_p) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num, points_p, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num, points_p, ref newloc))) { array[0] = newloc[0]; array[1] = newloc[1]; num4++; num5 = 1; } num2 = GetStarPoints(badotri, torg, tdest, tapex, 2, ref points_q); if (tdest.type == VertexType.FreeVertex && num2 != 0 && ValidPolygonAngles(num2, points_q) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num2, points_q, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num2, points_q, ref newloc))) { array[2] = newloc[0]; array[3] = newloc[1]; num4++; num6 = 2; } num3 = GetStarPoints(badotri, torg, tdest, tapex, 3, ref points_r); if (tapex.type == VertexType.FreeVertex && num3 != 0 && ValidPolygonAngles(num3, points_r) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num3, points_r, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num3, points_r, ref newloc))) { array[4] = newloc[0]; array[5] = newloc[1]; num4++; num7 = 3; } if (num4 > 0) { if (num5 > 0) { newloc[0] = array[0]; newloc[1] = array[1]; return num5; } if (num6 > 0) { newloc[0] = array[2]; newloc[1] = array[3]; return num6; } if (num7 > 0) { newloc[0] = array[4]; newloc[1] = array[5]; return num7; } } return 0; } private int GetStarPoints(Otri badotri, TriangleNet.Geometry.Vertex p, TriangleNet.Geometry.Vertex q, TriangleNet.Geometry.Vertex r, int whichPoint, ref float[] points) { Otri neighotri = default(Otri); float first_x = 0f; float first_y = 0f; float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; float[] thirdpoint = new float[2]; int num5 = 0; switch (whichPoint) { case 1: first_x = p.x; first_y = p.y; num = r.x; num2 = r.y; num3 = q.x; num4 = q.y; break; case 2: first_x = q.x; first_y = q.y; num = p.x; num2 = p.y; num3 = r.x; num4 = r.y; break; case 3: first_x = r.x; first_y = r.y; num = q.x; num2 = q.y; num3 = p.x; num4 = p.y; break; } Otri badotri2 = badotri; points[num5] = num; num5++; points[num5] = num2; num5++; thirdpoint[0] = num; thirdpoint[1] = num2; do { if (!GetNeighborsVertex(badotri2, first_x, first_y, num, num2, ref thirdpoint, ref neighotri)) { badotri2 = neighotri; num = thirdpoint[0]; num2 = thirdpoint[1]; points[num5] = thirdpoint[0]; num5++; points[num5] = thirdpoint[1]; num5++; continue; } num5 = 0; break; } while (!(Mathf.Abs(thirdpoint[0] - num3) <= 0f) || !(Mathf.Abs(thirdpoint[1] - num4) <= 0f)); return num5 / 2; } private bool GetNeighborsVertex(Otri badotri, float first_x, float first_y, float second_x, float second_y, ref float[] thirdpoint, ref Otri neighotri) { Otri ot = default(Otri); bool result = false; TriangleNet.Geometry.Vertex vertex = null; TriangleNet.Geometry.Vertex vertex2 = null; TriangleNet.Geometry.Vertex vertex3 = null; int num = 0; int num2 = 0; badotri.orient = 0; while (badotri.orient < 3) { badotri.Sym(ref ot); if (ot.tri.id != -1) { vertex = ot.Org(); vertex2 = ot.Dest(); vertex3 = ot.Apex(); if ((vertex.x != vertex2.x || vertex.y != vertex2.y) && (vertex2.x != vertex3.x || vertex2.y != vertex3.y) && (vertex.x != vertex3.x || vertex.y != vertex3.y)) { num = 0; if (Mathf.Abs(first_x - vertex.x) < 0f && Mathf.Abs(first_y - vertex.y) < 0f) { num = 11; } else if (Mathf.Abs(first_x - vertex2.x) < 0f && Mathf.Abs(first_y - vertex2.y) < 0f) { num = 12; } else if (Mathf.Abs(first_x - vertex3.x) < 0f && Mathf.Abs(first_y - vertex3.y) < 0f) { num = 13; } num2 = 0; if (Mathf.Abs(second_x - vertex.x) < 0f && Mathf.Abs(second_y - vertex.y) < 0f) { num2 = 21; } else if (Mathf.Abs(second_x - vertex2.x) < 0f && Mathf.Abs(second_y - vertex2.y) < 0f) { num2 = 22; } else if (Mathf.Abs(second_x - vertex3.x) < 0f && Mathf.Abs(second_y - vertex3.y) < 0f) { num2 = 23; } } } if ((num == 11 && (num2 == 22 || num2 == 23)) || (num == 12 && (num2 == 21 || num2 == 23)) || (num == 13 && (num2 == 21 || num2 == 22))) { break; } badotri.orient++; } switch (num) { case 0: result = true; break; case 11: switch (num2) { case 22: thirdpoint[0] = vertex3.x; thirdpoint[1] = vertex3.y; break; case 23: thirdpoint[0] = vertex2.x; thirdpoint[1] = vertex2.y; break; default: result = true; break; } break; case 12: switch (num2) { case 21: thirdpoint[0] = vertex3.x; thirdpoint[1] = vertex3.y; break; case 23: thirdpoint[0] = vertex.x; thirdpoint[1] = vertex.y; break; default: result = true; break; } break; case 13: switch (num2) { case 21: thirdpoint[0] = vertex2.x; thirdpoint[1] = vertex2.y; break; case 22: thirdpoint[0] = vertex.x; thirdpoint[1] = vertex.y; break; default: result = true; break; } break; default: if (num2 == 0) { result = true; } break; } neighotri = ot; return result; } private bool GetWedgeIntersectionWithoutMaxAngle(int numpoints, float[] points, ref float[] newloc) { if (2 * numpoints > petalx.Length) { petalx = new float[2 * numpoints]; petaly = new float[2 * numpoints]; petalr = new float[2 * numpoints]; wedges = new float[2 * numpoints * 16 + 36]; } float[] p = new float[3]; int num = 0; float num2 = points[2 * numpoints - 4]; float num3 = points[2 * numpoints - 3]; float num4 = points[2 * numpoints - 2]; float num5 = points[2 * numpoints - 1]; float num6 = behavior.MinAngle * MathF.PI / 180f; float num7; float num8; if (behavior.goodAngle == 1f) { num7 = 0f; num8 = 0f; } else { num7 = 0.5f / Mathf.Tan(num6); num8 = 0.5f / Mathf.Sin(num6); } for (int i = 0; i < numpoints * 2; i += 2) { float num9 = points[i]; float num10 = points[i + 1]; float num11 = num4 - num2; float num12 = num5 - num3; float num13 = Mathf.Sqrt(num11 * num11 + num12 * num12); petalx[i / 2] = num2 + 0.5f * num11 - num7 * num12; petaly[i / 2] = num3 + 0.5f * num12 + num7 * num11; petalr[i / 2] = num8 * num13; petalx[numpoints + i / 2] = petalx[i / 2]; petaly[numpoints + i / 2] = petaly[i / 2]; petalr[numpoints + i / 2] = petalr[i / 2]; float num14 = (num2 + num4) / 2f; float num15 = (num3 + num5) / 2f; float num16 = Mathf.Sqrt((petalx[i / 2] - num14) * (petalx[i / 2] - num14) + (petaly[i / 2] - num15) * (petaly[i / 2] - num15)); float num17 = (petalx[i / 2] - num14) / num16; float num18 = (petaly[i / 2] - num15) / num16; float num19 = petalx[i / 2] + num17 * petalr[i / 2]; float num20 = petaly[i / 2] + num18 * petalr[i / 2]; num17 = num4 - num2; num18 = num5 - num3; float num21 = num4 * Mathf.Cos(num6) - num5 * Mathf.Sin(num6) + num2 - num2 * Mathf.Cos(num6) + num3 * Mathf.Sin(num6); float num22 = num4 * Mathf.Sin(num6) + num5 * Mathf.Cos(num6) + num3 - num2 * Mathf.Sin(num6) - num3 * Mathf.Cos(num6); wedges[i * 16] = num2; wedges[i * 16 + 1] = num3; wedges[i * 16 + 2] = num21; wedges[i * 16 + 3] = num22; num17 = num2 - num4; num18 = num3 - num5; float num23 = num2 * Mathf.Cos(num6) + num3 * Mathf.Sin(num6) + num4 - num4 * Mathf.Cos(num6) - num5 * Mathf.Sin(num6); float num24 = (0f - num2) * Mathf.Sin(num6) + num3 * Mathf.Cos(num6) + num5 + num4 * Mathf.Sin(num6) - num5 * Mathf.Cos(num6); wedges[i * 16 + 4] = num23; wedges[i * 16 + 5] = num24; wedges[i * 16 + 6] = num4; wedges[i * 16 + 7] = num5; num17 = num19 - petalx[i / 2]; num18 = num20 - petaly[i / 2]; float num25 = num19; float num26 = num20; for (int j = 1; j < 4; j++) { float num27 = num19 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j); float num28 = (0f - num19) * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] + petalx[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j); wedges[i * 16 + 8 + 4 * (j - 1)] = num27; wedges[i * 16 + 9 + 4 * (j - 1)] = num28; wedges[i * 16 + 10 + 4 * (j - 1)] = num25; wedges[i * 16 + 11 + 4 * (j - 1)] = num26; num25 = num27; num26 = num28; } num25 = num19; num26 = num20; for (int j = 1; j < 4; j++) { float num29 = num19 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) - num20 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j); float num30 = num19 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] - petalx[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j); wedges[i * 16 + 20 + 4 * (j - 1)] = num25; wedges[i * 16 + 21 + 4 * (j - 1)] = num26; wedges[i * 16 + 22 + 4 * (j - 1)] = num29; wedges[i * 16 + 23 + 4 * (j - 1)] = num30; num25 = num29; num26 = num30; } if (i == 0) { LineLineIntersection(num2, num3, num21, num22, num4, num5, num23, num24, ref p); if (p[0] == 1f) { initialConvexPoly[0] = p[1]; initialConvexPoly[1] = p[2]; initialConvexPoly[2] = wedges[i * 16 + 16]; initialConvexPoly[3] = wedges[i * 16 + 17]; initialConvexPoly[4] = wedges[i * 16 + 12]; initialConvexPoly[5] = wedges[i * 16 + 13]; initialConvexPoly[6] = wedges[i * 16 + 8]; initialConvexPoly[7] = wedges[i * 16 + 9]; initialConvexPoly[8] = num19; initialConvexPoly[9] = num20; initialConvexPoly[10] = wedges[i * 16 + 22]; initialConvexPoly[11] = wedges[i * 16 + 23]; initialConvexPoly[12] = wedges[i * 16 + 26]; initialConvexPoly[13] = wedges[i * 16 + 27]; initialConvexPoly[14] = wedges[i * 16 + 30]; initialConvexPoly[15] = wedges[i * 16 + 31]; } } num2 = num4; num3 = num5; num4 = num9; num5 = num10; } if (numpoints != 0) { int num31 = (numpoints - 1) / 2 + 1; int num32 = 0; int num33 = 0; int i = 1; int numvertices = 8; for (int j = 0; j < 32; j += 4) { num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[32 * num31 + j], wedges[32 * num31 + 1 + j], wedges[32 * num31 + 2 + j], wedges[32 * num31 + 3 + j]); if (num == 0) { return false; } numvertices = num; } for (num33++; num33 < numpoints - 1; num33++) { for (int j = 0; j < 32; j += 4) { num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[32 * (i + num31 * num32) + j], wedges[32 * (i + num31 * num32) + 1 + j], wedges[32 * (i + num31 * num32) + 2 + j], wedges[32 * (i + num31 * num32) + 3 + j]); if (num == 0) { return false; } numvertices = num; } i += num32; num32 = (num32 + 1) % 2; } FindPolyCentroid(num, initialConvexPoly, ref newloc); if (!behavior.fixedArea) { return true; } } return false; } private bool GetWedgeIntersection(int numpoints, float[] points, ref float[] newloc) { if (2 * numpoints > petalx.Length) { petalx = new float[2 * numpoints]; petaly = new float[2 * numpoints]; petalr = new float[2 * numpoints]; wedges = new float[2 * numpoints * 20 + 40]; } float[] p = new float[3]; float[] p2 = new float[3]; float[] p3 = new float[3]; float[] p4 = new float[3]; int num = 0; int num2 = 0; float num3 = 4f; float num4 = 4f; float num5 = points[2 * numpoints - 4]; float num6 = points[2 * numpoints - 3]; float num7 = points[2 * numpoints - 2]; float num8 = points[2 * numpoints - 1]; float num9 = behavior.MinAngle * MathF.PI / 180f; float num10 = Mathf.Sin(num9); float num11 = Mathf.Cos(num9); float num12 = behavior.MaxAngle * MathF.PI / 180f; float num13 = Mathf.Sin(num12); float num14 = Mathf.Cos(num12); float num15; float num16; if ((double)behavior.goodAngle == 1.0) { num15 = 0f; num16 = 0f; } else { num15 = 0.5f / Mathf.Tan(num9); num16 = 0.5f / Mathf.Sin(num9); } for (int i = 0; i < numpoints * 2; i += 2) { float num17 = points[i]; float num18 = points[i + 1]; float num19 = num7 - num5; float num20 = num8 - num6; float num21 = Mathf.Sqrt(num19 * num19 + num20 * num20); petalx[i / 2] = num5 + 0.5f * num19 - num15 * num20; petaly[i / 2] = num6 + 0.5f * num20 + num15 * num19; petalr[i / 2] = num16 * num21; petalx[numpoints + i / 2] = petalx[i / 2]; petaly[numpoints + i / 2] = petaly[i / 2]; petalr[numpoints + i / 2] = petalr[i / 2]; float num22 = (num5 + num7) / 2f; float num23 = (num6 + num8) / 2f; float num24 = Mathf.Sqrt((petalx[i / 2] - num22) * (petalx[i / 2] - num22) + (petaly[i / 2] - num23) * (petaly[i / 2] - num23)); float num25 = (petalx[i / 2] - num22) / num24; float num26 = (petaly[i / 2] - num23) / num24; float num27 = petalx[i / 2] + num25 * petalr[i / 2]; float num28 = petaly[i / 2] + num26 * petalr[i / 2]; num25 = num7 - num5; num26 = num8 - num6; float num29 = num7 * num11 - num8 * num10 + num5 - num5 * num11 + num6 * num10; float num30 = num7 * num10 + num8 * num11 + num6 - num5 * num10 - num6 * num11; wedges[i * 20] = num5; wedges[i * 20 + 1] = num6; wedges[i * 20 + 2] = num29; wedges[i * 20 + 3] = num30; num25 = num5 - num7; num26 = num6 - num8; float num31 = num5 * num11 + num6 * num10 + num7 - num7 * num11 - num8 * num10; float num32 = (0f - num5) * num10 + num6 * num11 + num8 + num7 * num10 - num8 * num11; wedges[i * 20 + 4] = num31; wedges[i * 20 + 5] = num32; wedges[i * 20 + 6] = num7; wedges[i * 20 + 7] = num8; num25 = num27 - petalx[i / 2]; num26 = num28 - petaly[i / 2]; float num33 = num27; float num34 = num28; num9 = 2f * behavior.MaxAngle + behavior.MinAngle - 180f; if (num9 <= 0f) { num2 = 4; num3 = 1f; num4 = 1f; } else if (num9 <= 5f) { num2 = 6; num3 = 2f; num4 = 2f; } else if (num9 <= 10f) { num2 = 8; num3 = 3f; num4 = 3f; } else { num2 = 10; num3 = 4f; num4 = 4f; } num9 = num9 * MathF.PI / 180f; for (int j = 1; (float)j < num3; j++) { if (num3 != 1f) { float num35 = num27 * Mathf.Cos(num9 / (num3 - 1f) * (float)j) + num28 * Mathf.Sin(num9 / (num3 - 1f) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos(num9 / (num3 - 1f) * (float)j) - petaly[i / 2] * Mathf.Sin(num9 / (num3 - 1f) * (float)j); float num36 = (0f - num27) * Mathf.Sin(num9 / (num3 - 1f) * (float)j) + num28 * Mathf.Cos(num9 / (num3 - 1f) * (float)j) + petaly[i / 2] + petalx[i / 2] * Mathf.Sin(num9 / (num3 - 1f) * (float)j) - petaly[i / 2] * Mathf.Cos(num9 / (num3 - 1f) * (float)j); wedges[i * 20 + 8 + 4 * (j - 1)] = num35; wedges[i * 20 + 9 + 4 * (j - 1)] = num36; wedges[i * 20 + 10 + 4 * (j - 1)] = num33; wedges[i * 20 + 11 + 4 * (j - 1)] = num34; num33 = num35; num34 = num36; } } num25 = num5 - num7; num26 = num6 - num8; float num37 = num5 * num14 + num6 * num13 + num7 - num7 * num14 - num8 * num13; float num38 = (0f - num5) * num13 + num6 * num14 + num8 + num7 * num13 - num8 * num14; wedges[i * 20 + 20] = num7; wedges[i * 20 + 21] = num8; wedges[i * 20 + 22] = num37; wedges[i * 20 + 23] = num38; num33 = num27; num34 = num28; for (int j = 1; (float)j < num4; j++) { if (num4 != 1f) { float num39 = num27 * Mathf.Cos(num9 / (num4 - 1f) * (float)j) - num28 * Mathf.Sin(num9 / (num4 - 1f) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos(num9 / (num4 - 1f) * (float)j) + petaly[i / 2] * Mathf.Sin(num9 / (num4 - 1f) * (float)j); float num40 = num27 * Mathf.Sin(num9 / (num4 - 1f) * (float)j) + num28 * Mathf.Cos(num9 / (num4 - 1f) * (float)j) + petaly[i / 2] - petalx[i / 2] * Mathf.Sin(num9 / (num4 - 1f) * (float)j) - petaly[i / 2] * Mathf.Cos(num9 / (num4 - 1f) * (float)j); wedges[i * 20 + 24 + 4 * (j - 1)] = num33; wedges[i * 20 + 25 + 4 * (j - 1)] = num34; wedges[i * 20 + 26 + 4 * (j - 1)] = num39; wedges[i * 20 + 27 + 4 * (j - 1)] = num40; num33 = num39; num34 = num40; } } num25 = num7 - num5; num26 = num8 - num6; float num41 = num7 * num14 - num8 * num13 + num5 - num5 * num14 + num6 * num13; float num42 = num7 * num13 + num8 * num14 + num6 - num5 * num13 - num6 * num14; wedges[i * 20 + 36] = num41; wedges[i * 20 + 37] = num42; wedges[i * 20 + 38] = num5; wedges[i * 20 + 39] = num6; if (i == 0) { switch (num2) { case 4: LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p); LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2); LineLineIntersection(num5, num6, num41, num42, num7, num8, num37, num38, ref p3); LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p4); if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f && p4[0] == 1f) { initialConvexPoly[0] = p[1]; initialConvexPoly[1] = p[2]; initialConvexPoly[2] = p2[1]; initialConvexPoly[3] = p2[2]; initialConvexPoly[4] = p3[1]; initialConvexPoly[5] = p3[2]; initialConvexPoly[6] = p4[1]; initialConvexPoly[7] = p4[2]; } break; case 6: LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p); LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2); LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3); if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f) { initialConvexPoly[0] = p[1]; initialConvexPoly[1] = p[2]; initialConvexPoly[2] = p2[1]; initialConvexPoly[3] = p2[2]; initialConvexPoly[4] = wedges[i * 20 + 8]; initialConvexPoly[5] = wedges[i * 20 + 9]; initialConvexPoly[6] = num27; initialConvexPoly[7] = num28; initialConvexPoly[8] = wedges[i * 20 + 26]; initialConvexPoly[9] = wedges[i * 20 + 27]; initialConvexPoly[10] = p3[1]; initialConvexPoly[11] = p3[2]; } break; case 8: LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p); LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2); LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3); if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f) { initialConvexPoly[0] = p[1]; initialConvexPoly[1] = p[2]; initialConvexPoly[2] = p2[1]; initialConvexPoly[3] = p2[2]; initialConvexPoly[4] = wedges[i * 20 + 12]; initialConvexPoly[5] = wedges[i * 20 + 13]; initialConvexPoly[6] = wedges[i * 20 + 8]; initialConvexPoly[7] = wedges[i * 20 + 9]; initialConvexPoly[8] = num27; initialConvexPoly[9] = num28; initialConvexPoly[10] = wedges[i * 20 + 26]; initialConvexPoly[11] = wedges[i * 20 + 27]; initialConvexPoly[12] = wedges[i * 20 + 30]; initialConvexPoly[13] = wedges[i * 20 + 31]; initialConvexPoly[14] = p3[1]; initialConvexPoly[15] = p3[2]; } break; case 10: LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p); LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2); LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3); if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f) { initialConvexPoly[0] = p[1]; initialConvexPoly[1] = p[2]; initialConvexPoly[2] = p2[1]; initialConvexPoly[3] = p2[2]; initialConvexPoly[4] = wedges[i * 20 + 16]; initialConvexPoly[5] = wedges[i * 20 + 17]; initialConvexPoly[6] = wedges[i * 20 + 12]; initialConvexPoly[7] = wedges[i * 20 + 13]; initialConvexPoly[8] = wedges[i * 20 + 8]; initialConvexPoly[9] = wedges[i * 20 + 9]; initialConvexPoly[10] = num27; initialConvexPoly[11] = num28; initialConvexPoly[12] = wedges[i * 20 + 28]; initialConvexPoly[13] = wedges[i * 20 + 29]; initialConvexPoly[14] = wedges[i * 20 + 32]; initialConvexPoly[15] = wedges[i * 20 + 33]; initialConvexPoly[16] = wedges[i * 20 + 34]; initialConvexPoly[17] = wedges[i * 20 + 35]; initialConvexPoly[18] = p3[1]; initialConvexPoly[19] = p3[2]; } break; } } num5 = num7; num6 = num8; num7 = num17; num8 = num18; } if (numpoints != 0) { int num43 = (numpoints - 1) / 2 + 1; int num44 = 0; int num45 = 0; int i = 1; int numvertices = num2; for (int j = 0; j < 40; j += 4) { if ((num2 != 4 || (j != 8 && j != 12 && j != 16 && j != 24 && j != 28 && j != 32)) && (num2 != 6 || (j != 12 && j != 16 && j != 28 && j != 32)) && (num2 != 8 || (j != 16 && j != 32))) { num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[40 * num43 + j], wedges[40 * num43 + 1 + j], wedges[40 * num43 + 2 + j], wedges[40 * num43 + 3 + j]); if (num == 0) { return false; } numvertices = num; } } for (num45++; num45 < numpoints - 1; num45++) { for (int j = 0; j < 40; j += 4) { if ((num2 != 4 || (j != 8 && j != 12 && j != 16 && j != 24 && j != 28 && j != 32)) && (num2 != 6 || (j != 12 && j != 16 && j != 28 && j != 32)) && (num2 != 8 || (j != 16 && j != 32))) { num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[40 * (i + num43 * num44) + j], wedges[40 * (i + num43 * num44) + 1 + j], wedges[40 * (i + num43 * num44) + 2 + j], wedges[40 * (i + num43 * num44) + 3 + j]); if (num == 0) { return false; } numvertices = num; } } i += num44; num44 = (num44 + 1) % 2; } FindPolyCentroid(num, initialConvexPoly, ref newloc); if ((double)behavior.MaxAngle == 0.0) { return true; } int num46 = 0; for (int j = 0; j < numpoints * 2 - 2; j += 2) { if (IsBadTriangleAngle(newloc[0], newloc[1], points[j], points[j + 1], points[j + 2], points[j + 3])) { num46++; } } if (IsBadTriangleAngle(newloc[0], newloc[1], points[0], points[1], points[numpoints * 2 - 2], points[numpoints * 2 - 1])) { num46++; } if (num46 == 0) { return true; } int num47 = ((numpoints <= 2) ? 20 : 30); for (int k = 0; k < 2 * numpoints; k += 2) { for (int l = 1; l < num47; l++) { newloc[0] = 0f; newloc[1] = 0f; for (i = 0; i < 2 * numpoints; i += 2) { float num48 = 1f / (float)numpoints; if (i == k) { newloc[0] = newloc[0] + 0.1f * (float)l * num48 * points[i]; newloc[1] = newloc[1] + 0.1f * (float)l * num48 * points[i + 1]; } else { num48 = (1f - 0.1f * (float)l * num48) / (float)((double)numpoints - 1.0); newloc[0] = newloc[0] + num48 * points[i]; newloc[1] = newloc[1] + num48 * points[i + 1]; } } num46 = 0; for (int j = 0; j < numpoints * 2 - 2; j += 2) { if (IsBadTriangleAngle(newloc[0], newloc[1], points[j], points[j + 1], points[j + 2], points[j + 3])) { num46++; } } if (IsBadTriangleAngle(newloc[0], newloc[1], points[0], points[1], points[numpoints * 2 - 2], points[numpoints * 2 - 1])) { num46++; } if (num46 == 0) { return true; } } } } return false; } private bool ValidPolygonAngles(int numpoints, float[] points) { for (int i = 0; i < numpoints; i++) { if (i == numpoints - 1) { if (IsBadPolygonAngle(points[i * 2], points[i * 2 + 1], points[0], points[1], points[2], points[3])) { return false; } } else if (i == numpoints - 2) { if (IsBadPolygonAngle(points[i * 2], points[i * 2 + 1], points[(i + 1) * 2], points[(i + 1) * 2 + 1], points[0], points[1])) { return false; } } else if (IsBadPolygonAngle(points[i * 2], points[i * 2 + 1], points[(i + 1) * 2], points[(i + 1) * 2 + 1], points[(i + 2) * 2], points[(i + 2) * 2 + 1])) { return false; } } return true; } private bool IsBadPolygonAngle(float x1, float y1, float x2, float y2, float x3, float y3) { float num = x1 - x2; float num2 = y1 - y2; float num3 = x2 - x3; float num4 = y2 - y3; float num5 = x3 - x1; float num6 = y3 - y1; float num7 = num * num + num2 * num2; float num8 = num3 * num3 + num4 * num4; float num9 = num5 * num5 + num6 * num6; float num10 = (num7 + num8 - num9) / (2f * Mathf.Sqrt(num7) * Mathf.Sqrt(num8)); if (Mathf.Acos(num10) < 2f * Mathf.Acos(Mathf.Sqrt(behavior.goodAngle))) { return true; } return false; } private void LineLineIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, ref float[] p) { float num = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); float num2 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); float num3 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); if (Mathf.Abs(num - 0f) < 0f && Mathf.Abs(num3 - 0f) < 0f && Mathf.Abs(num2 - 0f) < 0f) { p[0] = 0f; return; } if (Mathf.Abs(num - 0f) < 0f) { p[0] = 0f; return; } p[0] = 1f; num2 /= num; num3 /= num; p[1] = x1 + num2 * (x2 - x1); p[2] = y1 + num2 * (y2 - y1); } private int HalfPlaneIntersection(int numvertices, ref float[] convexPoly, float x1, float y1, float x2, float y2) { float[] array = null; int i = 0; int num = 0; float num2 = x2 - x1; float num3 = y2 - y1; int num4 = SplitConvexPolygon(numvertices, convexPoly, x1, y1, x2, y2, polys); if (num4 == 3) { i = numvertices; } else { for (int j = 0; j < num4; j++) { float num5 = float.MaxValue; float num6 = float.MinValue; float num7; for (int k = 1; (float)k <= 2f * polys[j][0] - 1f; k += 2) { num7 = num2 * (polys[j][k + 1] - y1) - num3 * (polys[j][k] - x1); num5 = ((num7 < num5) ? num7 : num5); num6 = ((num7 > num6) ? num7 : num6); } num7 = ((Mathf.Abs(num5) > Mathf.Abs(num6)) ? num5 : num6); if (num7 > 0f) { array = polys[j]; num = 1; break; } } if (num == 1) { for (; (float)i < array[0]; i++) { convexPoly[2 * i] = array[2 * i + 1]; convexPoly[2 * i + 1] = array[2 * i + 2]; } } } return i; } private int SplitConvexPolygon(int numvertices, float[] convexPoly, float x1, float y1, float x2, float y2, float[][] polys) { int num = 0; float[] p = new float[3]; int num2 = 0; int num3 = 0; float num4 = 1E-12f; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int num10 = 0; int num11 = 0; int num12 = 0; for (int i = 0; i < 2 * numvertices; i += 2) { int num13 = ((i + 2 < 2 * numvertices) ? (i + 2) : 0); LineLineSegmentIntersection(x1, y1, x2, y2, convexPoly[i], convexPoly[i + 1], convexPoly[num13], convexPoly[num13 + 1], ref p); if (Mathf.Abs(p[0] - 0f) <= num4) { if (num == 1) { num3++; poly2[2 * num3 - 1] = convexPoly[num13]; poly2[2 * num3] = convexPoly[num13 + 1]; } else { num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; } num5++; continue; } if (Mathf.Abs(p[0] - 2f) <= num4) { num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; num6++; continue; } num7++; if (Mathf.Abs(p[1] - convexPoly[num13]) <= num4 && Mathf.Abs(p[2] - convexPoly[num13 + 1]) <= num4) { num8++; switch (num) { case 1: num3++; poly2[2 * num3 - 1] = convexPoly[num13]; poly2[2 * num3] = convexPoly[num13 + 1]; num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; num++; break; case 0: num11++; num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; if (i + 4 < 2 * numvertices) { int num14 = LinePointLocation(x1, y1, x2, y2, convexPoly[i], convexPoly[i + 1]); int num15 = LinePointLocation(x1, y1, x2, y2, convexPoly[i + 4], convexPoly[i + 5]); if (num14 != num15 && num14 != 0 && num15 != 0) { num12++; num3++; poly2[2 * num3 - 1] = convexPoly[num13]; poly2[2 * num3] = convexPoly[num13 + 1]; num++; } } break; } } else if (!(Mathf.Abs(p[1] - convexPoly[i]) <= num4) || !(Mathf.Abs(p[2] - convexPoly[i + 1]) <= num4)) { num9++; num2++; poly1[2 * num2 - 1] = p[1]; poly1[2 * num2] = p[2]; num3++; poly2[2 * num3 - 1] = p[1]; poly2[2 * num3] = p[2]; switch (num) { case 1: num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; break; case 0: num3++; poly2[2 * num3 - 1] = convexPoly[num13]; poly2[2 * num3] = convexPoly[num13 + 1]; break; } num++; } else { num10++; if (num == 1) { num3++; poly2[2 * num3 - 1] = convexPoly[num13]; poly2[2 * num3] = convexPoly[num13 + 1]; } else { num2++; poly1[2 * num2 - 1] = convexPoly[num13]; poly1[2 * num2] = convexPoly[num13 + 1]; } } } int result; if (num != 0 && num != 2) { result = 3; } else { result = ((num == 0) ? 1 : 2); poly1[0] = num2; poly2[0] = num3; polys[0] = poly1; if (num == 2) { polys[1] = poly2; } } return result; } private int LinePointLocation(float x1, float y1, float x2, float y2, float x, float y) { if (Mathf.Atan((y2 - y1) / (x2 - x1)) * 180f / MathF.PI == 90f) { if (Mathf.Abs(x1 - x) <= 1E-11f) { return 0; } } else if (Mathf.Abs(y1 + (y2 - y1) * (x - x1) / (x2 - x1) - y) <= 0f) { return 0; } float num = (x2 - x1) * (y - y1) - (y2 - y1) * (x - x1); if (Mathf.Abs(num - 0f) <= 1E-11f) { return 0; } if (num > 0f) { return 1; } return 2; } private void LineLineSegmentIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, ref float[] p) { float num = 1E-13f; float num2 = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); float num3 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); float num4 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); if (Mathf.Abs(num2 - 0f) < num) { if (Mathf.Abs(num4 - 0f) < num && Mathf.Abs(num3 - 0f) < num) { p[0] = 2f; } else { p[0] = 0f; } return; } num4 /= num2; num3 /= num2; if (num4 < 0f - num || num4 > 1f + num) { p[0] = 0f; return; } p[0] = 1f; p[1] = x1 + num3 * (x2 - x1); p[2] = y1 + num3 * (y2 - y1); } private void FindPolyCentroid(int numpoints, float[] points, ref float[] centroid) { centroid[0] = 0f; centroid[1] = 0f; for (int i = 0; i < 2 * numpoints; i += 2) { centroid[0] = centroid[0] + points[i]; centroid[1] = centroid[1] + points[i + 1]; } centroid[0] = centroid[0] / (float)numpoints; centroid[1] = centroid[1] / (float)numpoints; } private void CircleLineIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float r, ref float[] p) { float num = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); float num2 = 2f * ((x2 - x1) * (x1 - x3) + (y2 - y1) * (y1 - y3)); float num3 = x3 * x3 + y3 * y3 + x1 * x1 + y1 * y1 - 2f * (x3 * x1 + y3 * y1) - r * r; float num4 = num2 * num2 - 4f * num * num3; if (num4 < 0f) { p[0] = 0f; } else if (Mathf.Abs(num4 - 0f) < 0f) { p[0] = 1f; float num5 = (0f - num2) / (2f * num); p[1] = x1 + num5 * (x2 - x1); p[2] = y1 + num5 * (y2 - y1); } else if ((double)num4 > 0.0 && !(Mathf.Abs(num - 0f) < 0f)) { p[0] = 2f; float num5 = (0f - num2 + Mathf.Sqrt(num4)) / (2f * num); p[1] = x1 + num5 * (x2 - x1); p[2] = y1 + num5 * (y2 - y1); num5 = (0f - num2 - Mathf.Sqrt(num4)) / (2f * num); p[3] = x1 + num5 * (x2 - x1); p[4] = y1 + num5 * (y2 - y1); } else { p[0] = 0f; } } private bool ChooseCorrectPoint(float x1, float y1, float x2, float y2, float x3, float y3, bool isObtuse) { float num = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3); float num2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); if (isObtuse) { if (num2 >= num) { return true; } return false; } if (num2 < num) { return true; } return false; } private void PointBetweenPoints(float x1, float y1, float x2, float y2, float x, float y, ref float[] p) { if ((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y) < (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) { p[0] = 1f; p[1] = (x - x2) * (x - x2) + (y - y2) * (y - y2); p[2] = x; p[3] = y; } else { p[0] = 0f; p[1] = 0f; p[2] = 0f; p[3] = 0f; } } private bool IsBadTriangleAngle(float x1, float y1, float x2, float y2, float x3, float y3) { float num = x1 - x2; float num2 = y1 - y2; float num3 = x2 - x3; float num4 = y2 - y3; float num5 = x3 - x1; float num6 = y3 - y1; float num7 = num * num; float num8 = num2 * num2; float num9 = num3 * num3; float num10 = num4 * num4; float num11 = num5 * num5; float num12 = num6 * num6; float num13 = num7 + num8; float num14 = num9 + num10; float num15 = num11 + num12; float num16; if (num13 < num14 && num13 < num15) { num16 = num3 * num5 + num4 * num6; num16 = num16 * num16 / (num14 * num15); } else if (num14 < num15) { num16 = num * num5 + num2 * num6; num16 = num16 * num16 / (num13 * num15); } else { num16 = num * num3 + num2 * num4; num16 = num16 * num16 / (num13 * num14); } float num17 = ((num13 > num14 && num13 > num15) ? ((num14 + num15 - num13) / (2f * Mathf.Sqrt(num14 * num15))) : ((!(num14 > num15)) ? ((num13 + num14 - num15) / (2f * Mathf.Sqrt(num13 * num14))) : ((num13 + num15 - num14) / (2f * Mathf.Sqrt(num13 * num15))))); if (num16 > behavior.goodAngle || (behavior.MaxAngle != 0f && num17 < behavior.maxGoodAngle)) { return true; } return false; } private float MinDistanceToNeighbor(float newlocX, float newlocY, ref Otri searchtri) { Otri ot = default(Otri); LocateResult locateResult = LocateResult.Outside; Point point = new Point(newlocX, newlocY); TriangleNet.Geometry.Vertex vertex = searchtri.Org(); TriangleNet.Geometry.Vertex vertex2 = searchtri.Dest(); if (vertex.x == point.x && vertex.y == point.y) { locateResult = LocateResult.OnVertex; searchtri.Copy(ref ot); } else if (vertex2.x == point.x && vertex2.y == point.y) { searchtri.Lnext(); locateResult = LocateResult.OnVertex; searchtri.Copy(ref ot); } else { float num = predicates.CounterClockwise(vertex, vertex2, point); if (num < 0f) { searchtri.Sym(); searchtri.Copy(ref ot); locateResult = _TriangleNetMesh.locator.PreciseLocate(point, ref ot, stopatsubsegment: false); } else if (num == 0f) { if (vertex.x < point.x == point.x < vertex2.x && vertex.y < point.y == point.y < vertex2.y) { locateResult = LocateResult.OnEdge; searchtri.Copy(ref ot); } } else { searchtri.Copy(ref ot); locateResult = _TriangleNetMesh.locator.PreciseLocate(point, ref ot, stopatsubsegment: false); } } if (locateResult == LocateResult.OnVertex || locateResult == LocateResult.Outside) { return 0f; } TriangleNet.Geometry.Vertex vertex3 = ot.Org(); TriangleNet.Geometry.Vertex vertex4 = ot.Dest(); TriangleNet.Geometry.Vertex vertex5 = ot.Apex(); float num2 = (vertex3.x - point.x) * (vertex3.x - point.x) + (vertex3.y - point.y) * (vertex3.y - point.y); float num3 = (vertex4.x - point.x) * (vertex4.x - point.x) + (vertex4.y - point.y) * (vertex4.y - point.y); float num4 = (vertex5.x - point.x) * (vertex5.x - point.x) + (vertex5.y - point.y) * (vertex5.y - point.y); if (num2 <= num3 && num2 <= num4) { return num2; } if (num3 <= num4) { return num3; } return num4; } } public class RobustPredicates : IPredicates { private static readonly object creationLock; private static RobustPredicates _default; private static float epsilon; private static float splitter; private static float resulterrbound; private static float ccwerrboundA; private static float ccwerrboundB; private static float ccwerrboundC; private static float iccerrboundA; private static float iccerrboundB; private static float iccerrboundC; private float[] fin1; private float[] fin2; private float[] abdet; private float[] axbc; private float[] axxbc; private float[] aybc; private float[] ayybc; private float[] adet; private float[] bxca; private float[] bxxca; private float[] byca; private float[] byyca; private float[] bdet; private float[] cxab; private float[] cxxab; private float[] cyab; private float[] cyyab; private float[] cdet; private float[] temp8; private float[] temp16a; private float[] temp16b; private float[] temp16c; private float[] temp32a; private float[] temp32b; private float[] temp48; private float[] temp64; public static RobustPredicates Default { get { if (_default == null) { lock (creationLock) { if (_default == null) { _default = new RobustPredicates(); } } } return _default; } } static RobustPredicates() { creationLock = new object(); bool flag = true; float num = 0.5f; epsilon = 1f; splitter = 1f; float num2 = 1f; float num3; do { num3 = num2; epsilon *= num; if (flag) { splitter *= 2f; } flag = !flag; num2 = 1f + epsilon; } while (num2 != 1f && num2 != num3); splitter += 1f; resulterrbound = (3f + 8f * epsilon) * epsilon; ccwerrboundA = (3f + 16f * epsilon) * epsilon; ccwerrboundB = (2f + 12f * epsilon) * epsilon; ccwerrboundC = (9f + 64f * epsilon) * epsilon * epsilon; iccerrboundA = (10f + 96f * epsilon) * epsilon; iccerrboundB = (4f + 48f * epsilon) * epsilon; iccerrboundC = (44f + 576f * epsilon) * epsilon * epsilon; } public RobustPredicates() { AllocateWorkspace(); } public float CounterClockwise(Point pa, Point pb, Point pc) { Statistic.CounterClockwiseCount++; float num = (pa.x - pc.x) * (pb.y - pc.y); float num2 = (pa.y - pc.y) * (pb.x - pc.x); float num3 = num - num2; if (Behavior.NoExact) { return num3; } float num4; if (num > 0f) { if (num2 <= 0f) { return num3; } num4 = num + num2; } else { if (!(num < 0f)) { return num3; } if (num2 >= 0f) { return num3; } num4 = 0f - num - num2; } float num5 = ccwerrboundA * num4; if (num3 >= num5 || 0f - num3 >= num5) { return num3; } Statistic.CounterClockwiseAdaptCount++; return CounterClockwiseAdapt(pa, pb, pc, num4); } public float InCircle(Point pa, Point pb, Point pc, Point pd) { Statistic.InCircleCount++; float num = pa.x - pd.x; float num2 = pb.x - pd.x; float num3 = pc.x - pd.x; float num4 = pa.y - pd.y; float num5 = pb.y - pd.y; float num6 = pc.y - pd.y; float num7 = num2 * num6; float num8 = num3 * num5; float num9 = num * num + num4 * num4; float num10 = num3 * num4; float num11 = num * num6; float num12 = num2 * num2 + num5 * num5; float num13 = num * num5; float num14 = num2 * num4; float num15 = num3 * num3 + num6 * num6; float num16 = num9 * (num7 - num8) + num12 * (num10 - num11) + num15 * (num13 - num14); if (Behavior.NoExact) { return num16; } float num17 = (Math.Abs(num7) + Math.Abs(num8)) * num9 + (Math.Abs(num10) + Math.Abs(num11)) * num12 + (Math.Abs(num13) + Math.Abs(num14)) * num15; float num18 = iccerrboundA * num17; if (num16 > num18 || 0f - num16 > num18) { return num16; } Statistic.InCircleAdaptCount++; return InCircleAdapt(pa, pb, pc, pd, num17); } public float NonRegular(Point pa, Point pb, Point pc, Point pd) { return InCircle(pa, pb, pc, pd); } public Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta, float offconstant) { Statistic.CircumcenterCount++; float num = dest.x - org.x; float num2 = dest.y - org.y; float num3 = apex.x - org.x; float num4 = apex.y - org.y; float num5 = num * num + num2 * num2; float num6 = num3 * num3 + num4 * num4; float num7 = (dest.x - apex.x) * (dest.x - apex.x) + (dest.y - apex.y) * (dest.y - apex.y); float num8; if (Behavior.NoExact) { num8 = 0.5f / (num * num4 - num3 * num2); } else { num8 = 0.5f / CounterClockwise(dest, apex, org); Statistic.CounterClockwiseCount--; } float num9 = (num4 * num5 - num2 * num6) * num8; float num10 = (num * num6 - num3 * num5) * num8; if (num5 < num6 && num5 < num7) { if (offconstant > 0f) { float num11 = 0.5f * num - offconstant * num2; float num12 = 0.5f * num2 + offconstant * num; if (num11 * num11 + num12 * num12 < num9 * num9 + num10 * num10) { num9 = num11; num10 = num12; } } } else if (num6 < num7) { if (offconstant > 0f) { float num11 = 0.5f * num3 + offconstant * num4; float num12 = 0.5f * num4 - offconstant * num3; if (num11 * num11 + num12 * num12 < num9 * num9 + num10 * num10) { num9 = num11; num10 = num12; } } } else if (offconstant > 0f) { float num11 = 0.5f * (apex.x - dest.x) - offconstant * (apex.y - dest.y); float num12 = 0.5f * (apex.y - dest.y) + offconstant * (apex.x - dest.x); if (num11 * num11 + num12 * num12 < (num9 - num) * (num9 - num) + (num10 - num2) * (num10 - num2)) { num9 = num + num11; num10 = num2 + num12; } } xi = (num4 * num9 - num3 * num10) * (2f * num8); eta = (num * num10 - num2 * num9) * (2f * num8); return new Point(org.x + num9, org.y + num10); } public Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta) { Statistic.CircumcenterCount++; float num = dest.x - org.x; float num2 = dest.y - org.y; float num3 = apex.x - org.x; float num4 = apex.y - org.y; float num5 = num * num + num2 * num2; float num6 = num3 * num3 + num4 * num4; float num7; if (Behavior.NoExact) { num7 = 0.5f / (num * num4 - num3 * num2); } else { num7 = 0.5f / CounterClockwise(dest, apex, org); Statistic.CounterClockwiseCount--; } float num8 = (num4 * num5 - num2 * num6) * num7; float num9 = (num * num6 - num3 * num5) * num7; xi = (num4 * num8 - num3 * num9) * (2f * num7); eta = (num * num9 - num2 * num8) * (2f * num7); return new Point(org.x + num8, org.y + num9); } private int FastExpansionSumZeroElim(int elen, float[] e, int flen, float[] f, float[] h) { float num = e[0]; float num2 = f[0]; int num3; int num4 = (num3 = 0); float num5; if (num2 > num == num2 > 0f - num) { num5 = num; num = e[++num4]; } else { num5 = num2; num2 = f[++num3]; } int num6 = 0; if (num4 < elen && num3 < flen) { float num7; float num9; if (num2 > num == num2 > 0f - num) { num7 = num + num5; float num8 = num7 - num; num9 = num5 - num8; num = e[++num4]; } else { num7 = num2 + num5; float num8 = num7 - num2; num9 = num5 - num8; num2 = f[++num3]; } num5 = num7; if (num9 != 0f) { h[num6++] = num9; } while (num4 < elen && num3 < flen) { if (num2 > num == num2 > 0f - num) { num7 = num5 + num; float num8 = num7 - num5; float num10 = num7 - num8; float num11 = num - num8; float num12 = num5 - num10; num9 = num12 + num11; num = e[++num4]; } else { num7 = num5 + num2; float num8 = num7 - num5; float num10 = num7 - num8; float num11 = num2 - num8; float num12 = num5 - num10; num9 = num12 + num11; num2 = f[++num3]; } num5 = num7; if (num9 != 0f) { h[num6++] = num9; } } } while (num4 < elen) { float num7 = num5 + num; float num8 = num7 - num5; float num10 = num7 - num8; float num11 = num - num8; float num12 = num5 - num10; float num9 = num12 + num11; num = e[++num4]; num5 = num7; if ((double)num9 != 0.0) { h[num6++] = num9; } } while (num3 < flen) { float num7 = num5 + num2; float num8 = num7 - num5; float num10 = num7 - num8; float num11 = num2 - num8; float num12 = num5 - num10; float num9 = num12 + num11; num2 = f[++num3]; num5 = num7; if (num9 != 0f) { h[num6++] = num9; } } if (num5 != 0f || num6 == 0) { h[num6++] = num5; } return num6; } private int ScaleExpansionZeroElim(int elen, float[] e, float b, float[] h) { float num = splitter * b; float num2 = num - b; float num3 = num - num2; float num4 = b - num3; float num5 = e[0] * b; num = splitter * e[0]; num2 = num - e[0]; float num6 = num - num2; float num7 = e[0] - num6; float num8 = num5 - num6 * num3; float num9 = num8 - num7 * num3; float num10 = num9 - num6 * num4; float num11 = num7 * num4 - num10; int num12 = 0; if (num11 != 0f) { h[num12++] = num11; } for (int i = 1; i < elen; i++) { float num13 = e[i]; float num14 = num13 * b; num = splitter * num13; num2 = num - num13; num6 = num - num2; num7 = num13 - num6; num8 = num14 - num6 * num3; num9 = num8 - num7 * num3; num10 = num9 - num6 * num4; float num15 = num7 * num4 - num10; float num16 = num5 + num15; float num17 = num16 - num5; float num18 = num16 - num17; float num19 = num15 - num17; float num20 = num5 - num18; num11 = num20 + num19; if (num11 != 0f) { h[num12++] = num11; } num5 = num14 + num16; num17 = num5 - num14; num11 = num16 - num17; if (num11 != 0f) { h[num12++] = num11; } } if (num5 != 0f || num12 == 0) { h[num12++] = num5; } return num12; } private float Estimate(int elen, float[] e) { float num = e[0]; for (int i = 1; i < elen; i++) { num += e[i]; } return num; } private float CounterClockwiseAdapt(Point pa, Point pb, Point pc, float detsum) { float[] array = new float[5]; float[] array2 = new float[5]; float[] array3 = new float[8]; float[] array4 = new float[12]; float[] array5 = new float[16]; float num = pa.x - pc.x; float num2 = pb.x - pc.x; float num3 = pa.y - pc.y; float num4 = pb.y - pc.y; float num5 = num * num4; float num6 = splitter * num; float num7 = num6 - num; float num8 = num6 - num7; float num9 = num - num8; num6 = splitter * num4; num7 = num6 - num4; float num10 = num6 - num7; float num11 = num4 - num10; float num12 = num5 - num8 * num10; float num13 = num12 - num9 * num10; float num14 = num13 - num8 * num11; float num15 = num9 * num11 - num14; float num16 = num3 * num2; num6 = splitter * num3; num7 = num6 - num3; num8 = num6 - num7; num9 = num3 - num8; num6 = splitter * num2; num7 = num6 - num2; num10 = num6 - num7; num11 = num2 - num10; num12 = num16 - num8 * num10; num13 = num12 - num9 * num10; num14 = num13 - num8 * num11; float num17 = num9 * num11 - num14; float num18 = num15 - num17; float num19 = num15 - num18; float num20 = num18 + num19; float num21 = num19 - num17; float num22 = num15 - num20; array[0] = num22 + num21; float num23 = num5 + num18; num19 = num23 - num5; num20 = num23 - num19; num21 = num18 - num19; num22 = num5 - num20; float num24 = num22 + num21; num18 = num24 - num16; num19 = num24 - num18; num20 = num18 + num19; num21 = num19 - num16; num22 = num24 - num20; array[1] = num22 + num21; float num25 = num23 + num18; num19 = num25 - num23; num20 = num25 - num19; num21 = num18 - num19; num22 = num23 - num20; array[2] = num22 + num21; array[3] = num25; float num26 = Estimate(4, array); float num27 = ccwerrboundB * detsum; if (num26 >= num27 || 0f - num26 >= num27) { return num26; } num19 = pa.x - num; num20 = num + num19; num21 = num19 - pc.x; num22 = pa.x - num20; float num28 = num22 + num21; num19 = pb.x - num2; num20 = num2 + num19; num21 = num19 - pc.x; num22 = pb.x - num20; float num29 = num22 + num21; num19 = pa.y - num3; num20 = num3 + num19; num21 = num19 - pc.y; num22 = pa.y - num20; float num30 = num22 + num21; num19 = pb.y - num4; num20 = num4 + num19; num21 = num19 - pc.y; num22 = pb.y - num20; float num31 = num22 + num21; if (num28 == 0f && num30 == 0f && num29 == 0f && num31 == 0f) { return num26; } num27 = ccwerrboundC * detsum + resulterrbound * ((num26 >= 0f) ? num26 : (0f - num26)); num26 += num * num31 + num4 * num28 - (num3 * num29 + num2 * num30); if (num26 >= num27 || 0f - num26 >= num27) { return num26; } float num32 = num28 * num4; num6 = splitter * num28; num7 = num6 - num28; num8 = num6 - num7; num9 = num28 - num8; num6 = splitter * num4; num7 = num6 - num4; num10 = num6 - num7; num11 = num4 - num10; num12 = num32 - num8 * num10; num13 = num12 - num9 * num10; num14 = num13 - num8 * num11; float num33 = num9 * num11 - num14; float num34 = num30 * num2; num6 = splitter * num30; num7 = num6 - num30; num8 = num6 - num7; num9 = num30 - num8; num6 = splitter * num2; num7 = num6 - num2; num10 = num6 - num7; num11 = num2 - num10; num12 = num34 - num8 * num10; num13 = num12 - num9 * num10; num14 = num13 - num8 * num11; float num35 = num9 * num11 - num14; num18 = num33 - num35; num19 = num33 - num18; num20 = num18 + num19; num21 = num19 - num35; num22 = num33 - num20; array2[0] = num22 + num21; num23 = num32 + num18; num19 = num23 - num32; num20 = num23 - num19; num21 = num18 - num19; num22 = num32 - num20; num24 = num22 + num21; num18 = num24 - num34; num19 = num24 - num18; num20 = num18 + num19; num21 = num19 - num34; num22 = num24 - num20; array2[1] = num22 + num21; float num36 = num23 + num18; num19 = num36 - num23; num20 = num36 - num19; num21 = num18 - num19; num22 = num23 - num20; array2[2] = num22 + num21; array2[3] = num36; int elen = FastExpansionSumZeroElim(4, array, 4, array2, array3); num32 = num * num31; num6 = splitter * num; num7 = num6 - num; num8 = num6 - num7; num9 = num - num8; num6 = splitter * num31; num7 = num6 - num31; num10 = num6 - num7; num11 = num31 - num10; num12 = num32 - num8 * num10; num13 = num12 - num9 * num10; num14 = num13 - num8 * num11; num33 = num9 * num11 - num14; num34 = num3 * num29; num6 = splitter * num3; num7 = num6 - num3; num8 = num6 - num7; num9 = num3 - num8; num6 = splitter * num29; num7 = num6 - nu