IntMath.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. using System;
  2. using UnityEngine;
  3. public class IntMath
  4. {
  5. public static VFactor atan2(int y, int x)
  6. {
  7. int num;
  8. int num2;
  9. if (x < 0)
  10. {
  11. if (y < 0)
  12. {
  13. x = -x;
  14. y = -y;
  15. num = 1;
  16. }
  17. else
  18. {
  19. x = -x;
  20. num = -1;
  21. }
  22. num2 = -31416;
  23. }
  24. else
  25. {
  26. if (y < 0)
  27. {
  28. y = -y;
  29. num = -1;
  30. }
  31. else
  32. {
  33. num = 1;
  34. }
  35. num2 = 0;
  36. }
  37. int dIM = Atan2LookupTable.DIM;
  38. long num3 = (long)(dIM - 1);
  39. long b = (long)((x >= y) ? x : y);
  40. int num4 = (int)IntMath.Divide((long)x * num3, b);
  41. int num5 = (int)IntMath.Divide((long)y * num3, b);
  42. int num6 = Atan2LookupTable.table[num5 * dIM + num4];
  43. return new VFactor
  44. {
  45. nom = (long)((num6 + num2) * num),
  46. den = 10000L
  47. };
  48. }
  49. public static VFactor acos(long nom, long den)
  50. {
  51. int num = (int)IntMath.Divide(nom * (long)AcosLookupTable.HALF_COUNT, den) + AcosLookupTable.HALF_COUNT;
  52. num = Mathf.Clamp(num, 0, AcosLookupTable.COUNT);
  53. return new VFactor
  54. {
  55. nom = (long)AcosLookupTable.table[num],
  56. den = 10000L
  57. };
  58. }
  59. public static VFactor sin(long nom, long den)
  60. {
  61. int index = SinCosLookupTable.getIndex(nom, den);
  62. return new VFactor((long)SinCosLookupTable.sin_table[index], (long)SinCosLookupTable.FACTOR);
  63. }
  64. public static VFactor cos(long nom, long den)
  65. {
  66. int index = SinCosLookupTable.getIndex(nom, den);
  67. return new VFactor((long)SinCosLookupTable.cos_table[index], (long)SinCosLookupTable.FACTOR);
  68. }
  69. public static void sincos(out VFactor s, out VFactor c, long nom, long den)
  70. {
  71. int index = SinCosLookupTable.getIndex(nom, den);
  72. s = new VFactor((long)SinCosLookupTable.sin_table[index], (long)SinCosLookupTable.FACTOR);
  73. c = new VFactor((long)SinCosLookupTable.cos_table[index], (long)SinCosLookupTable.FACTOR);
  74. }
  75. public static void sincos(out VFactor s, out VFactor c, VFactor angle)
  76. {
  77. int index = SinCosLookupTable.getIndex(angle.nom, angle.den);
  78. s = new VFactor((long)SinCosLookupTable.sin_table[index], (long)SinCosLookupTable.FACTOR);
  79. c = new VFactor((long)SinCosLookupTable.cos_table[index], (long)SinCosLookupTable.FACTOR);
  80. }
  81. public static long Divide(long a, long b)
  82. {
  83. long num = (long)((ulong)((a ^ b) & -9223372036854775808L) >> 63);
  84. long num2 = num * -2L + 1L;
  85. return (a + b / 2L * num2) / b;
  86. }
  87. public static int Divide(int a, int b)
  88. {
  89. int num = (int)((uint)((a ^ b) & -2147483648) >> 31);
  90. int num2 = num * -2 + 1;
  91. return (a + b / 2 * num2) / b;
  92. }
  93. public static VInt3 Divide(VInt3 a, long m, long b)
  94. {
  95. a.x = (int)IntMath.Divide((long)a.x * m, b);
  96. a.y = (int)IntMath.Divide((long)a.y * m, b);
  97. a.z = (int)IntMath.Divide((long)a.z * m, b);
  98. return a;
  99. }
  100. public static VInt2 Divide(VInt2 a, long m, long b)
  101. {
  102. a.x = (int)IntMath.Divide((long)a.x * m, b);
  103. a.y = (int)IntMath.Divide((long)a.y * m, b);
  104. return a;
  105. }
  106. public static VInt3 Divide(VInt3 a, int b)
  107. {
  108. a.x = IntMath.Divide(a.x, b);
  109. a.y = IntMath.Divide(a.y, b);
  110. a.z = IntMath.Divide(a.z, b);
  111. return a;
  112. }
  113. public static VInt3 Divide(VInt3 a, long b)
  114. {
  115. a.x = (int)IntMath.Divide((long)a.x, b);
  116. a.y = (int)IntMath.Divide((long)a.y, b);
  117. a.z = (int)IntMath.Divide((long)a.z, b);
  118. return a;
  119. }
  120. public static VInt2 Divide(VInt2 a, long b)
  121. {
  122. a.x = (int)IntMath.Divide((long)a.x, b);
  123. a.y = (int)IntMath.Divide((long)a.y, b);
  124. return a;
  125. }
  126. public static uint Sqrt32(uint a)
  127. {
  128. uint num = 0u;
  129. uint num2 = 0u;
  130. for (int i = 0; i < 16; i++)
  131. {
  132. num2 <<= 1;
  133. num <<= 2;
  134. num += a >> 30;
  135. a <<= 2;
  136. if (num2 < num)
  137. {
  138. num2 += 1u;
  139. num -= num2;
  140. num2 += 1u;
  141. }
  142. }
  143. return num2 >> 1 & 65535u;
  144. }
  145. public static ulong Sqrt64(ulong a)
  146. {
  147. ulong num = 0uL;
  148. ulong num2 = 0uL;
  149. for (int i = 0; i < 32; i++)
  150. {
  151. num2 <<= 1;
  152. num <<= 2;
  153. num += a >> 62;
  154. a <<= 2;
  155. if (num2 < num)
  156. {
  157. num2 += 1uL;
  158. num -= num2;
  159. num2 += 1uL;
  160. }
  161. }
  162. return num2 >> 1 & 0xffffffffu;
  163. }
  164. public static long SqrtLong(long a)
  165. {
  166. if (a <= 0L)
  167. {
  168. return 0L;
  169. }
  170. if (a <= (long)(0xffffffffu))
  171. {
  172. return (long)((ulong)IntMath.Sqrt32((uint)a));
  173. }
  174. return (long)IntMath.Sqrt64((ulong)a);
  175. }
  176. public static int Sqrt(long a)
  177. {
  178. if (a <= 0L)
  179. {
  180. return 0;
  181. }
  182. if (a <= (long)(0xffffffffu))
  183. {
  184. return (int)IntMath.Sqrt32((uint)a);
  185. }
  186. return (int)IntMath.Sqrt64((ulong)a);
  187. }
  188. public static long Clamp(long a, long min, long max)
  189. {
  190. if (a < min)
  191. {
  192. return min;
  193. }
  194. if (a > max)
  195. {
  196. return max;
  197. }
  198. return a;
  199. }
  200. public static long Max(long a, long b)
  201. {
  202. return (a <= b) ? b : a;
  203. }
  204. public static VInt3 Transform(ref VInt3 point, ref VInt3 axis_x, ref VInt3 axis_y, ref VInt3 axis_z, ref VInt3 trans)
  205. {
  206. return new VInt3(IntMath.Divide(axis_x.x * point.x + axis_y.x * point.y + axis_z.x * point.z, 1000) + trans.x, IntMath.Divide(axis_x.y * point.x + axis_y.y * point.y + axis_z.y * point.z, 1000) + trans.y, IntMath.Divide(axis_x.z * point.x + axis_y.z * point.y + axis_z.z * point.z, 1000) + trans.z);
  207. }
  208. public static VInt3 Transform(VInt3 point, ref VInt3 axis_x, ref VInt3 axis_y, ref VInt3 axis_z, ref VInt3 trans)
  209. {
  210. return new VInt3(IntMath.Divide(axis_x.x * point.x + axis_y.x * point.y + axis_z.x * point.z, 1000) + trans.x, IntMath.Divide(axis_x.y * point.x + axis_y.y * point.y + axis_z.y * point.z, 1000) + trans.y, IntMath.Divide(axis_x.z * point.x + axis_y.z * point.y + axis_z.z * point.z, 1000) + trans.z);
  211. }
  212. public static VInt3 Transform(ref VInt3 point, ref VInt3 axis_x, ref VInt3 axis_y, ref VInt3 axis_z, ref VInt3 trans, ref VInt3 scale)
  213. {
  214. long num = (long)point.x * (long)scale.x;
  215. long num2 = (long)point.y * (long)scale.x;
  216. long num3 = (long)point.z * (long)scale.x;
  217. return new VInt3((int)IntMath.Divide((long)axis_x.x * num + (long)axis_y.x * num2 + (long)axis_z.x * num3, 1000000L) + trans.x, (int)IntMath.Divide((long)axis_x.y * num + (long)axis_y.y * num2 + (long)axis_z.y * num3, 1000000L) + trans.y, (int)IntMath.Divide((long)axis_x.z * num + (long)axis_y.z * num2 + (long)axis_z.z * num3, 1000000L) + trans.z);
  218. }
  219. public static VInt3 Transform(ref VInt3 point, ref VInt3 forward, ref VInt3 trans)
  220. {
  221. VInt3 up = VInt3.up;
  222. VInt3 vInt = VInt3.Cross(VInt3.up, forward);
  223. return IntMath.Transform(ref point, ref vInt, ref up, ref forward, ref trans);
  224. }
  225. public static VInt3 Transform(VInt3 point, VInt3 forward, VInt3 trans)
  226. {
  227. VInt3 up = VInt3.up;
  228. VInt3 vInt = VInt3.Cross(VInt3.up, forward);
  229. return IntMath.Transform(ref point, ref vInt, ref up, ref forward, ref trans);
  230. }
  231. public static VInt3 Transform(VInt3 point, VInt3 forward, VInt3 trans, VInt3 scale)
  232. {
  233. VInt3 up = VInt3.up;
  234. VInt3 vInt = VInt3.Cross(VInt3.up, forward);
  235. return IntMath.Transform(ref point, ref vInt, ref up, ref forward, ref trans, ref scale);
  236. }
  237. public static int Lerp(int src, int dest, int nom, int den)
  238. {
  239. return IntMath.Divide(src * den + (dest - src) * nom, den);
  240. }
  241. public static long Lerp(long src, long dest, long nom, long den)
  242. {
  243. return IntMath.Divide(src * den + (dest - src) * nom, den);
  244. }
  245. public static bool IsPowerOfTwo(int x)
  246. {
  247. return (x & x - 1) == 0;
  248. }
  249. public static int CeilPowerOfTwo(int x)
  250. {
  251. x--;
  252. x |= x >> 1;
  253. x |= x >> 2;
  254. x |= x >> 4;
  255. x |= x >> 8;
  256. x |= x >> 16;
  257. x++;
  258. return x;
  259. }
  260. public static void SegvecToLinegen(ref VInt2 segSrc, ref VInt2 segVec, out long a, out long b, out long c)
  261. {
  262. a = (long)segVec.y;
  263. b = (long)(-(long)segVec.x);
  264. c = (long)segVec.x * (long)segSrc.y - (long)segSrc.x * (long)segVec.y;
  265. }
  266. private static bool IsPointOnSegment(ref VInt2 segSrc, ref VInt2 segVec, long x, long y)
  267. {
  268. long num = x - (long)segSrc.x;
  269. long num2 = y - (long)segSrc.y;
  270. return (long)segVec.x * num + (long)segVec.y * num2 >= 0L && num * num + num2 * num2 <= segVec.sqrMagnitudeLong;
  271. }
  272. public static bool IntersectSegment(ref VInt2 seg1Src, ref VInt2 seg1Vec, ref VInt2 seg2Src, ref VInt2 seg2Vec, out VInt2 interPoint)
  273. {
  274. long num;
  275. long num2;
  276. long num3;
  277. IntMath.SegvecToLinegen(ref seg1Src, ref seg1Vec, out num, out num2, out num3);
  278. long num4;
  279. long num5;
  280. long num6;
  281. IntMath.SegvecToLinegen(ref seg2Src, ref seg2Vec, out num4, out num5, out num6);
  282. long num7 = num * num5 - num4 * num2;
  283. if (num7 != 0L)
  284. {
  285. long num8 = IntMath.Divide(num2 * num6 - num5 * num3, num7);
  286. long num9 = IntMath.Divide(num4 * num3 - num * num6, num7);
  287. bool result = IntMath.IsPointOnSegment(ref seg1Src, ref seg1Vec, num8, num9) && IntMath.IsPointOnSegment(ref seg2Src, ref seg2Vec, num8, num9);
  288. interPoint.x = (int)num8;
  289. interPoint.y = (int)num9;
  290. return result;
  291. }
  292. interPoint = VInt2.zero;
  293. return false;
  294. }
  295. public static bool PointInPolygon(ref VInt2 pnt, VInt2[] plg)
  296. {
  297. if (plg == null || plg.Length < 3)
  298. {
  299. return false;
  300. }
  301. bool flag = false;
  302. int i = 0;
  303. int num = plg.Length - 1;
  304. while (i < plg.Length)
  305. {
  306. VInt2 vInt = plg[i];
  307. VInt2 vInt2 = plg[num];
  308. if ((vInt.y <= pnt.y && pnt.y < vInt2.y) || (vInt2.y <= pnt.y && pnt.y < vInt.y))
  309. {
  310. int num2 = vInt2.y - vInt.y;
  311. long num3 = (long)(pnt.y - vInt.y) * (long)(vInt2.x - vInt.x) - (long)(pnt.x - vInt.x) * (long)num2;
  312. if (num2 > 0)
  313. {
  314. if (num3 > 0L)
  315. {
  316. flag = !flag;
  317. }
  318. }
  319. else if (num3 < 0L)
  320. {
  321. flag = !flag;
  322. }
  323. }
  324. num = i++;
  325. }
  326. return flag;
  327. }
  328. public static bool SegIntersectPlg(ref VInt2 segSrc, ref VInt2 segVec, VInt2[] plg, out VInt2 nearPoint, out VInt2 projectVec)
  329. {
  330. nearPoint = VInt2.zero;
  331. projectVec = VInt2.zero;
  332. if (plg == null || plg.Length < 2)
  333. {
  334. return false;
  335. }
  336. bool result = false;
  337. long num = -1L;
  338. int num2 = -1;
  339. for (int i = 0; i < plg.Length; i++)
  340. {
  341. VInt2 vInt = plg[(i + 1) % plg.Length] - plg[i];
  342. VInt2 vInt2;
  343. if (IntMath.IntersectSegment(ref segSrc, ref segVec, ref plg[i], ref vInt, out vInt2))
  344. {
  345. long sqrMagnitudeLong = (vInt2 - segSrc).sqrMagnitudeLong;
  346. if (num < 0L || sqrMagnitudeLong < num)
  347. {
  348. nearPoint = vInt2;
  349. num = sqrMagnitudeLong;
  350. num2 = i;
  351. result = true;
  352. }
  353. }
  354. }
  355. if (num2 >= 0)
  356. {
  357. VInt2 lhs = plg[(num2 + 1) % plg.Length] - plg[num2];
  358. VInt2 vInt3 = segSrc + segVec - nearPoint;
  359. long num3 = (long)vInt3.x * (long)lhs.x + (long)vInt3.y * (long)lhs.y;
  360. if (num3 < 0L)
  361. {
  362. num3 = -num3;
  363. lhs = -lhs;
  364. }
  365. long sqrMagnitudeLong2 = lhs.sqrMagnitudeLong;
  366. projectVec.x = (int)IntMath.Divide((long)lhs.x * num3, sqrMagnitudeLong2);
  367. projectVec.y = (int)IntMath.Divide((long)lhs.y * num3, sqrMagnitudeLong2);
  368. }
  369. return result;
  370. }
  371. }