You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
809 lines
41 KiB
809 lines
41 KiB
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Sog
|
|
{
|
|
public static class ILMath
|
|
{
|
|
#if USE_FLOAT
|
|
private static float[] s_Sin = new float[360]
|
|
{
|
|
0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f, 0.1045285f, 0.1218693f,
|
|
0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f, 0.2079117f, 0.2249510f, 0.2419219f, 0.2588190f,
|
|
0.2756373f, 0.2923717f, 0.3090170f, 0.3255681f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
|
|
0.4067366f, 0.4226182f, 0.4383711f, 0.4539905f, 0.4694715f, 0.4848096f, 0.5000000f, 0.5150381f,
|
|
0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f, 0.5877852f, 0.6018150f, 0.6156614f, 0.6293204f,
|
|
0.6427876f, 0.6560590f, 0.6691306f, 0.6819983f, 0.6946583f, 0.7071068f, 0.7193398f, 0.7313537f,
|
|
0.7431448f, 0.7547095f, 0.7660444f, 0.7771459f, 0.7880107f, 0.7986355f, 0.8090169f, 0.8191520f,
|
|
0.8290375f, 0.8386706f, 0.8480481f, 0.8571673f, 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f,
|
|
0.8987940f, 0.9063078f, 0.9135454f, 0.9205048f, 0.9271838f, 0.9335804f, 0.9396926f, 0.9455186f,
|
|
0.9510565f, 0.9563047f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f, 0.9781476f, 0.9816272f,
|
|
0.9848077f, 0.9876883f, 0.9902681f, 0.9925461f, 0.9945219f, 0.9961947f, 0.9975640f, 0.9986295f,
|
|
0.9993908f, 0.9998477f, 1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
|
|
0.9945219f, 0.9925461f, 0.9902681f, 0.9876884f, 0.9848078f, 0.9816272f, 0.9781476f, 0.9743701f,
|
|
0.9702957f, 0.9659259f, 0.9612617f, 0.9563048f, 0.9510565f, 0.9455186f, 0.9396927f, 0.9335805f,
|
|
0.9271839f, 0.9205049f, 0.9135455f, 0.9063078f, 0.8987941f, 0.8910066f, 0.8829476f, 0.8746198f,
|
|
0.8660254f, 0.8571674f, 0.8480482f, 0.8386706f, 0.8290376f, 0.8191521f, 0.8090171f, 0.7986356f,
|
|
0.7880108f, 0.7771460f, 0.7660445f, 0.7547097f, 0.7431449f, 0.7313538f, 0.7193399f, 0.7071069f,
|
|
0.6946585f, 0.6819984f, 0.6691307f, 0.6560591f, 0.6427877f, 0.6293205f, 0.6156616f, 0.6018151f,
|
|
0.5877854f, 0.5735765f, 0.5591930f, 0.5446391f, 0.5299194f, 0.5150382f, 0.5000001f, 0.4848097f,
|
|
0.4694717f, 0.4539906f, 0.4383713f, 0.4226184f, 0.4067368f, 0.3907312f, 0.3746067f, 0.3583681f,
|
|
0.3420203f, 0.3255683f, 0.3090171f, 0.2923718f, 0.2756375f, 0.2588192f, 0.2419220f, 0.2249512f,
|
|
0.2079118f, 0.1908091f, 0.1736483f, 0.1564346f, 0.1391732f, 0.1218695f, 0.1045286f, 0.0871559f,
|
|
0.0697566f, 0.0523361f, 0.0348996f, 0.0174526f, 0.0000002f, -0.0174523f, -0.0348993f, -0.0523358f,
|
|
-0.0697563f, -0.0871556f, -0.1045283f, -0.1218692f, -0.1391729f, -0.1564343f, -0.1736480f, -0.1908088f,
|
|
-0.2079115f, -0.2249509f, -0.2419217f, -0.2588189f, -0.2756372f, -0.2923715f, -0.3090168f, -0.3255680f,
|
|
-0.3420200f, -0.3583678f, -0.3746064f, -0.3907310f, -0.4067365f, -0.4226181f, -0.4383710f, -0.4539903f,
|
|
-0.4694714f, -0.4848095f, -0.4999999f, -0.5150379f, -0.5299191f, -0.5446389f, -0.5591928f, -0.5735763f,
|
|
-0.5877851f, -0.6018149f, -0.6156613f, -0.6293203f, -0.6427875f, -0.6560589f, -0.6691304f, -0.6819983f,
|
|
-0.6946582f, -0.7071066f, -0.7193397f, -0.7313536f, -0.7431447f, -0.7547095f, -0.7660443f, -0.7771459f,
|
|
-0.7880107f, -0.7986354f, -0.8090169f, -0.8191519f, -0.8290375f, -0.8386704f, -0.8480480f, -0.8571672f,
|
|
-0.8660253f, -0.8746196f, -0.8829475f, -0.8910064f, -0.8987939f, -0.9063077f, -0.9135454f, -0.9205047f,
|
|
-0.9271837f, -0.9335803f, -0.9396926f, -0.9455185f, -0.9510565f, -0.9563047f, -0.9612616f, -0.9659258f,
|
|
-0.9702957f, -0.9743700f, -0.9781476f, -0.9816272f, -0.9848077f, -0.9876883f, -0.9902681f, -0.9925461f,
|
|
-0.9945219f, -0.9961947f, -0.9975640f, -0.9986295f, -0.9993908f, -0.9998477f, -1.0000000f, -0.9998477f,
|
|
-0.9993908f, -0.9986296f, -0.9975641f, -0.9961947f, -0.9945219f, -0.9925462f, -0.9902681f, -0.9876884f,
|
|
-0.9848078f, -0.9816272f, -0.9781476f, -0.9743701f, -0.9702958f, -0.9659259f, -0.9612617f, -0.9563048f,
|
|
-0.9510566f, -0.9455187f, -0.9396927f, -0.9335805f, -0.9271839f, -0.9205049f, -0.9135455f, -0.9063079f,
|
|
-0.8987942f, -0.8910066f, -0.8829477f, -0.8746198f, -0.8660255f, -0.8571674f, -0.8480482f, -0.8386707f,
|
|
-0.8290377f, -0.8191522f, -0.8090171f, -0.7986357f, -0.7880109f, -0.7771461f, -0.7660446f, -0.7547098f,
|
|
-0.7431450f, -0.7313539f, -0.7193400f, -0.7071069f, -0.6946586f, -0.6819986f, -0.6691308f, -0.6560592f,
|
|
-0.6427878f, -0.6293206f, -0.6156617f, -0.6018152f, -0.5877855f, -0.5735767f, -0.5591931f, -0.5446393f,
|
|
-0.5299195f, -0.5150383f, -0.5000002f, -0.4848099f, -0.4694718f, -0.4539908f, -0.4383714f, -0.4226185f,
|
|
-0.4067369f, -0.3907314f, -0.3746068f, -0.3583682f, -0.3420204f, -0.3255684f, -0.3090173f, -0.2923720f,
|
|
-0.2756376f, -0.2588193f, -0.2419222f, -0.2249513f, -0.2079120f, -0.1908093f, -0.1736485f, -0.1564348f,
|
|
-0.1391734f, -0.1218696f, -0.1045288f, -0.0871560f, -0.0697568f, -0.0523363f, -0.0348998f, -0.0174527f
|
|
};
|
|
|
|
private static float[] s_Cos = new float[360]
|
|
{
|
|
1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f, 0.9945219f, 0.9925461f,
|
|
0.9902681f, 0.9876884f, 0.9848077f, 0.9816272f, 0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f,
|
|
0.9612617f, 0.9563048f, 0.9510565f, 0.9455186f, 0.9396926f, 0.9335805f, 0.9271839f, 0.9205049f,
|
|
0.9135455f, 0.9063078f, 0.8987941f, 0.8910065f, 0.8829476f, 0.8746197f, 0.8660254f, 0.8571673f,
|
|
0.8480481f, 0.8386706f, 0.8290376f, 0.8191521f, 0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f,
|
|
0.7660444f, 0.7547096f, 0.7431449f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
|
|
0.6691306f, 0.6560591f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f, 0.5877853f, 0.5735765f,
|
|
0.5591930f, 0.5446391f, 0.5299193f, 0.5150381f, 0.5000001f, 0.4848097f, 0.4694716f, 0.4539905f,
|
|
0.4383712f, 0.4226183f, 0.4067367f, 0.3907312f, 0.3746066f, 0.3583680f, 0.3420202f, 0.3255682f,
|
|
0.3090171f, 0.2923717f, 0.2756374f, 0.2588191f, 0.2419220f, 0.2249511f, 0.2079118f, 0.1908091f,
|
|
0.1736482f, 0.1564345f, 0.1391732f, 0.1218694f, 0.1045285f, 0.0871558f, 0.0697565f, 0.0523360f,
|
|
0.0348996f, 0.0174525f, 0.0000001f, -0.0174523f, -0.0348994f, -0.0523359f, -0.0697564f, -0.0871557f,
|
|
-0.1045284f, -0.1218693f, -0.1391730f, -0.1564344f, -0.1736481f, -0.1908089f, -0.2079116f, -0.2249510f,
|
|
-0.2419218f, -0.2588190f, -0.2756373f, -0.2923716f, -0.3090169f, -0.3255681f, -0.3420201f, -0.3583679f,
|
|
-0.3746065f, -0.3907310f, -0.4067366f, -0.4226182f, -0.4383711f, -0.4539904f, -0.4694715f, -0.4848095f,
|
|
-0.4999999f, -0.5150380f, -0.5299192f, -0.5446389f, -0.5591928f, -0.5735763f, -0.5877852f, -0.6018149f,
|
|
-0.6156614f, -0.6293203f, -0.6427875f, -0.6560590f, -0.6691305f, -0.6819983f, -0.6946583f, -0.7071067f,
|
|
-0.7193397f, -0.7313536f, -0.7431448f, -0.7547095f, -0.7660444f, -0.7771459f, -0.7880107f, -0.7986354f,
|
|
-0.8090169f, -0.8191520f, -0.8290375f, -0.8386705f, -0.8480480f, -0.8571672f, -0.8660253f, -0.8746197f,
|
|
-0.8829475f, -0.8910065f, -0.8987940f, -0.9063078f, -0.9135454f, -0.9205048f, -0.9271838f, -0.9335804f,
|
|
-0.9396926f, -0.9455186f, -0.9510565f, -0.9563047f, -0.9612616f, -0.9659258f, -0.9702957f, -0.9743701f,
|
|
-0.9781476f, -0.9816272f, -0.9848077f, -0.9876883f, -0.9902681f, -0.9925461f, -0.9945219f, -0.9961947f,
|
|
-0.9975640f, -0.9986295f, -0.9993908f, -0.9998477f, -1.0000000f, -0.9998477f, -0.9993908f, -0.9986296f,
|
|
-0.9975641f, -0.9961947f, -0.9945219f, -0.9925461f, -0.9902681f, -0.9876884f, -0.9848078f, -0.9816272f,
|
|
-0.9781476f, -0.9743701f, -0.9702958f, -0.9659259f, -0.9612617f, -0.9563048f, -0.9510565f, -0.9455186f,
|
|
-0.9396927f, -0.9335805f, -0.9271839f, -0.9205049f, -0.9135455f, -0.9063079f, -0.8987941f, -0.8910066f,
|
|
-0.8829477f, -0.8746198f, -0.8660255f, -0.8571674f, -0.8480482f, -0.8386707f, -0.8290377f, -0.8191522f,
|
|
-0.8090171f, -0.7986356f, -0.7880109f, -0.7771461f, -0.7660446f, -0.7547097f, -0.7431449f, -0.7313538f,
|
|
-0.7193399f, -0.7071069f, -0.6946585f, -0.6819985f, -0.6691307f, -0.6560591f, -0.6427878f, -0.6293206f,
|
|
-0.6156616f, -0.6018152f, -0.5877854f, -0.5735766f, -0.5591931f, -0.5446392f, -0.5299194f, -0.5150383f,
|
|
-0.5000002f, -0.4848098f, -0.4694718f, -0.4539907f, -0.4383713f, -0.4226184f, -0.4067368f, -0.3907313f,
|
|
-0.3746068f, -0.3583682f, -0.3420203f, -0.3255683f, -0.3090172f, -0.2923719f, -0.2756376f, -0.2588193f,
|
|
-0.2419221f, -0.2249513f, -0.2079119f, -0.1908092f, -0.1736484f, -0.1564347f, -0.1391733f, -0.1218696f,
|
|
-0.1045287f, -0.0871560f, -0.0697567f, -0.0523362f, -0.0348997f, -0.0174526f, -0.0000002f, 0.0174522f,
|
|
0.0348993f, 0.0523357f, 0.0697562f, 0.0871555f, 0.1045282f, 0.1218691f, 0.1391729f, 0.1564342f,
|
|
0.1736479f, 0.1908088f, 0.2079115f, 0.2249508f, 0.2419217f, 0.2588188f, 0.2756371f, 0.2923715f,
|
|
0.3090168f, 0.3255679f, 0.3420199f, 0.3583677f, 0.3746064f, 0.3907309f, 0.4067364f, 0.4226180f,
|
|
0.4383709f, 0.4539903f, 0.4694713f, 0.4848094f, 0.4999998f, 0.5150378f, 0.5299190f, 0.5446388f,
|
|
0.5591927f, 0.5735762f, 0.5877851f, 0.6018148f, 0.6156613f, 0.6293202f, 0.6427874f, 0.6560588f,
|
|
0.6691304f, 0.6819982f, 0.6946582f, 0.7071066f, 0.7193396f, 0.7313535f, 0.7431446f, 0.7547094f,
|
|
0.7660443f, 0.7771458f, 0.7880106f, 0.7986354f, 0.8090168f, 0.8191519f, 0.8290374f, 0.8386704f,
|
|
0.8480480f, 0.8571672f, 0.8660253f, 0.8746195f, 0.8829474f, 0.8910064f, 0.8987939f, 0.9063077f,
|
|
0.9135454f, 0.9205047f, 0.9271837f, 0.9335803f, 0.9396925f, 0.9455185f, 0.9510564f, 0.9563047f,
|
|
0.9612616f, 0.9659258f, 0.9702957f, 0.9743700f, 0.9781476f, 0.9816271f, 0.9848077f, 0.9876883f,
|
|
0.9902681f, 0.9925461f, 0.9945219f, 0.9961947f, 0.9975640f, 0.9986295f, 0.9993908f, 0.9998477f
|
|
};
|
|
|
|
public static float Sin(int angle)
|
|
{
|
|
angle = (360 + angle % 360) % 360;
|
|
return s_Sin[angle];
|
|
}
|
|
|
|
public static float Cos(int angle)
|
|
{
|
|
angle = (360 + angle % 360) % 360;
|
|
return s_Cos[angle];
|
|
}
|
|
#else
|
|
|
|
private static readonly int[] s_Sin = new int[360]
|
|
{
|
|
0, 17, 34, 52, 69, 87, 104, 121, 139, 156, 173, 190, 207, 224, 241, 258, 275, 292, 309, 325, 342, 358, 374, 390, 406, 422, 438, 453, 469, 484,
|
|
499, 515, 529, 544, 559, 573, 587, 601, 615, 629, 642, 656, 669, 681, 694, 707, 719, 731, 743, 754, 766, 777, 788, 798, 809, 819, 829, 838, 848, 857,
|
|
866, 874, 882, 891, 898, 906, 913, 920, 927, 933, 939, 945, 951, 956, 961, 965, 970, 974, 978, 981, 984, 987, 990, 992, 994, 996, 997, 998, 999, 999,
|
|
1000, 999, 999, 998, 997, 996, 994, 992, 990, 987, 984, 981, 978, 974, 970, 965, 961, 956, 951, 945, 939, 933, 927, 920, 913, 906, 898, 891, 882, 874,
|
|
866, 857, 848, 838, 829, 819, 809, 798, 788, 777, 766, 754, 743, 731, 719, 707, 694, 681, 669, 656, 642, 629, 615, 601, 587, 573, 559, 544, 529, 515,
|
|
499, 484, 469, 453, 438, 422, 406, 390, 374, 358, 342, 325, 309, 292, 275, 258, 241, 224, 207, 190, 173, 156, 139, 121, 104, 87, 69, 52, 34, 17,
|
|
0, -17, -34, -52, -69, -87, -104, -121, -139, -156, -173, -190, -207, -224, -241, -258, -275, -292, -309, -325, -342, -358, -374, -390, -406, -422, -438, -453, -469, -484,
|
|
-500, -515, -529, -544, -559, -573, -587, -601, -615, -629, -642, -656, -669, -681, -694, -707, -719, -731, -743, -754, -766, -777, -788, -798, -809, -819, -829, -838, -848, -857,
|
|
-866, -874, -882, -891, -898, -906, -913, -920, -927, -933, -939, -945, -951, -956, -961, -965, -970, -974, -978, -981, -984, -987, -990, -992, -994, -996, -997, -998, -999, -999,
|
|
-1000, -999, -999, -998, -997, -996, -994, -992, -990, -987, -984, -981, -978, -974, -970, -965, -961, -956, -951, -945, -939, -933, -927, -920, -913, -906, -898, -891, -882, -874,
|
|
-866, -857, -848, -838, -829, -819, -809, -798, -788, -777, -766, -754, -743, -731, -719, -707, -694, -681, -669, -656, -642, -629, -615, -601, -587, -573, -559, -544, -529, -515,
|
|
-500, -484, -469, -453, -438, -422, -406, -390, -374, -358, -342, -325, -309, -292, -275, -258, -241, -224, -207, -190, -173, -156, -139, -121, -104, -87, -69, -52, -34, -17,
|
|
};
|
|
|
|
private static readonly int[] s_Cos = new int[360]
|
|
{
|
|
1000, 999, 999, 998, 997, 996, 994, 992, 990, 987, 984, 981, 978, 974, 970, 965, 961, 956, 951, 945, 939, 933, 927, 920, 913, 906, 898, 891, 882, 874,
|
|
866, 857, 848, 838, 829, 819, 809, 798, 788, 777, 766, 754, 743, 731, 719, 707, 694, 681, 669, 656, 642, 629, 615, 601, 587, 573, 559, 544, 529, 515,
|
|
500, 484, 469, 453, 438, 422, 406, 390, 374, 358, 342, 325, 309, 292, 275, 258, 241, 224, 207, 190, 173, 156, 139, 121, 104, 87, 69, 52, 34, 17,
|
|
0, -17, -34, -52, -69, -87, -104, -121, -139, -156, -173, -190, -207, -224, -241, -258, -275, -292, -309, -325, -342, -358, -374, -390, -406, -422, -438, -453, -469, -484,
|
|
-499, -515, -529, -544, -559, -573, -587, -601, -615, -629, -642, -656, -669, -681, -694, -707, -719, -731, -743, -754, -766, -777, -788, -798, -809, -819, -829, -838, -848, -857,
|
|
-866, -874, -882, -891, -898, -906, -913, -920, -927, -933, -939, -945, -951, -956, -961, -965, -970, -974, -978, -981, -984, -987, -990, -992, -994, -996, -997, -998, -999, -999,
|
|
-1000, -999, -999, -998, -997, -996, -994, -992, -990, -987, -984, -981, -978, -974, -970, -965, -961, -956, -951, -945, -939, -933, -927, -920, -913, -906, -898, -891, -882, -874,
|
|
-866, -857, -848, -838, -829, -819, -809, -798, -788, -777, -766, -754, -743, -731, -719, -707, -694, -681, -669, -656, -642, -629, -615, -601, -587, -573, -559, -544, -529, -515,
|
|
-500, -484, -469, -453, -438, -422, -406, -390, -374, -358, -342, -325, -309, -292, -275, -258, -241, -224, -207, -190, -173, -156, -139, -121, -104, -87, -69, -52, -34, -17,
|
|
0, 17, 34, 52, 69, 87, 104, 121, 139, 156, 173, 190, 207, 224, 241, 258, 275, 292, 309, 325, 342, 358, 374, 390, 406, 422, 438, 453, 469, 484,
|
|
500, 515, 529, 544, 559, 573, 587, 601, 615, 629, 642, 656, 669, 681, 694, 707, 719, 731, 743, 754, 766, 777, 788, 798, 809, 819, 829, 838, 848, 857,
|
|
866, 874, 882, 891, 898, 906, 913, 920, 927, 933, 939, 945, 951, 956, 961, 965, 970, 974, 978, 981, 984, 987, 990, 992, 994, 996, 997, 998, 999, 999,
|
|
};
|
|
|
|
public static int Sin(int angle)
|
|
{
|
|
angle = (360 + angle % 360) % 360;
|
|
return s_Sin[angle];
|
|
}
|
|
|
|
public static int Cos(int angle)
|
|
{
|
|
angle = (360 + angle % 360) % 360;
|
|
return s_Cos[angle];
|
|
}
|
|
|
|
#endif
|
|
|
|
private static readonly int[] s_ATan = new int[960]
|
|
{
|
|
0,1,1,2,2,3,4,4,5,5,6,6,7,7,8,9,9,10,10,11,11,12,12,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,
|
|
22,22,23,23,24,24,25,25,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,33,33,34,34,34,35,35,36,36,36,37,37,37,38,38,
|
|
39,39,39,40,40,40,41,41,41,41,42,42,42,43,43,43,44,44,44,45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48,49,49,49,49,50,
|
|
50,50,50,51,51,51,51,52,52,52,52,52,53,53,53,53,53,54,54,54,54,54,55,55,55,55,55,55,56,56,56,56,56,57,57,57,57,57,57,57,
|
|
58,58,58,58,58,58,59,59,59,59,59,59,59,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,62,62,62,62,62,62,62,62,63,63,63,63,
|
|
63,63,63,63,63,64,64,64,64,64,64,64,64,64,65,65,65,65,65,65,65,65,65,65,66,66,66,66,66,66,66,66,66,66,66,67,67,67,67,67,
|
|
67,67,67,67,67,67,67,68,68,68,68,68,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69,69,69,69,69,69,69,69,70,70,70,70,70,70,
|
|
70,70,70,70,70,70,70,70,70,70,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,72,72,72,72,72,
|
|
72,72,72,72,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,74,74,74,74,74,74,74,74,74,
|
|
74,74,74,74,74,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
|
|
75,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,
|
|
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,78,78,78,78,78,78,78,78,78,78,
|
|
78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,79,79,79,79,79,79,
|
|
79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
|
|
79,79,79,79,79,79,79,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
|
|
80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,81,81,81,81,81,81,81,81,81,
|
|
81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
|
|
81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,82,82,82,82,82,82,82,82,82,
|
|
82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
|
|
82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
|
|
82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
|
|
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
|
|
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
|
|
83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,84,84,84,84,84,84,84,84,84
|
|
};
|
|
|
|
private static readonly int[] s_ACos = new int[1001]
|
|
{
|
|
90,90,90,90,90,90,90,90,90,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,88,88,88,88,88,88,88,88,88,88,88,88,88,
|
|
88,88,88,88,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,85,
|
|
85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,83,83,83,83,83,83,
|
|
83,83,83,83,83,83,83,83,83,83,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,81,81,81,81,81,81,81,81,81,81,81,81,
|
|
81,81,81,81,81,81,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
|
|
78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,76,76,76,76,76,76,
|
|
76,76,76,76,76,76,76,76,76,76,76,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,74,74,74,74,74,74,74,74,74,74,74,74,
|
|
74,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,71,71,
|
|
71,71,71,71,71,71,71,71,71,71,71,71,71,71,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,69,69,69,69,69,69,69,69,69,
|
|
69,69,69,69,69,69,69,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,66,
|
|
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,64,64,64,64,64,64,64,64,64,
|
|
64,64,64,64,64,64,64,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,61,61,
|
|
61,61,61,61,61,61,61,61,61,61,61,61,61,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,59,59,59,59,59,59,59,59,59,59,59,59,
|
|
59,59,59,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,57,57,57,57,57,57,57,57,57,57,57,57,57,57,56,56,56,56,56,56,56,56,
|
|
56,56,56,56,56,56,56,55,55,55,55,55,55,55,55,55,55,55,55,55,55,54,54,54,54,54,54,54,54,54,54,54,54,54,54,53,53,53,53,53,
|
|
53,53,53,53,53,53,53,53,53,52,52,52,52,52,52,52,52,52,52,52,52,52,52,51,51,51,51,51,51,51,51,51,51,51,51,51,51,50,50,50,
|
|
50,50,50,50,50,50,50,50,50,50,49,49,49,49,49,49,49,49,49,49,49,49,49,48,48,48,48,48,48,48,48,48,48,48,48,48,47,47,47,47,
|
|
47,47,47,47,47,47,47,47,47,46,46,46,46,46,46,46,46,46,46,46,46,45,45,45,45,45,45,45,45,45,45,45,45,45,44,44,44,44,44,44,
|
|
44,44,44,44,44,44,43,43,43,43,43,43,43,43,43,43,43,43,42,42,42,42,42,42,42,42,42,42,42,41,41,41,41,41,41,41,41,41,41,41,
|
|
41,40,40,40,40,40,40,40,40,40,40,40,39,39,39,39,39,39,39,39,39,39,39,38,38,38,38,38,38,38,38,38,38,38,37,37,37,37,37,37,
|
|
37,37,37,37,36,36,36,36,36,36,36,36,36,36,36,35,35,35,35,35,35,35,35,35,35,34,34,34,34,34,34,34,34,34,33,33,33,33,33,33,
|
|
33,33,33,33,32,32,32,32,32,32,32,32,32,31,31,31,31,31,31,31,31,31,30,30,30,30,30,30,30,30,30,29,29,29,29,29,29,29,29,28,
|
|
28,28,28,28,28,28,28,28,27,27,27,27,27,27,27,26,26,26,26,26,26,26,26,25,25,25,25,25,25,25,24,24,24,24,24,24,24,24,23,23,
|
|
23,23,23,23,22,22,22,22,22,22,22,21,21,21,21,21,21,20,20,20,20,20,20,19,19,19,19,19,19,18,18,18,18,18,17,17,17,17,17,16,
|
|
16,16,16,16,15,15,15,15,15,14,14,14,14,13,13,13,13,12,12,12,11,11,11,11,10,10,10,9,9,9,8,8,7,7,6,6,5,4,4,3,0
|
|
};
|
|
|
|
|
|
public static int GetAngle(int x1, int y1, int x2, int y2)
|
|
{
|
|
int angle = 0;
|
|
if (x1 == x2)
|
|
{
|
|
if (y2 >= y1)
|
|
{
|
|
angle = 90;
|
|
}
|
|
else
|
|
{
|
|
angle = 270;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int tan = (y2 - y1) * 100 / (x2 - x1);
|
|
|
|
int idx = tan;
|
|
if (idx < 0)
|
|
{
|
|
idx = -idx;
|
|
}
|
|
|
|
if (idx < 960)
|
|
{
|
|
angle = s_ATan[idx];
|
|
}
|
|
else if (idx >= 960 && idx < 1143)
|
|
{
|
|
angle = 84;
|
|
}
|
|
else if (idx >= 1143 && idx < 1430)
|
|
{
|
|
angle = 85;
|
|
}
|
|
else if (idx >= 1430 && idx < 1908)
|
|
{
|
|
angle = 86;
|
|
}
|
|
else if (idx >= 1908 && idx < 2863)
|
|
{
|
|
angle = 87;
|
|
}
|
|
else if (idx >= 2863 && idx < 5728)
|
|
{
|
|
angle = 88;
|
|
}
|
|
else if (idx >= 5728)
|
|
{
|
|
angle = 89;
|
|
}
|
|
|
|
if (tan >= 0)
|
|
{
|
|
if (x2 < x1) // 第三坐标系
|
|
{
|
|
angle += 180;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (y2 >= y1) // 第二坐标系
|
|
{
|
|
angle = 180 - angle;
|
|
}
|
|
else //第四坐标系
|
|
{
|
|
angle = 360 - angle;
|
|
}
|
|
}
|
|
}
|
|
return angle;
|
|
}
|
|
|
|
public static int GetAngleACos(int acos)
|
|
{
|
|
if (acos >= 0)
|
|
{
|
|
if (acos > 1000)
|
|
{
|
|
acos = 1000;
|
|
}
|
|
|
|
return s_ACos[acos];
|
|
}
|
|
|
|
if (acos < -1000)
|
|
{
|
|
acos = -1000;
|
|
}
|
|
|
|
return 180 - s_ACos[-acos];
|
|
}
|
|
|
|
|
|
// 角度为笛卡尔坐标(水平为0度,逆时针为正向)
|
|
public static bool IsCollisionCircleRect(int circleX, int circleY, int radius,
|
|
int rectX, int rectY, int length, int width, int angle)
|
|
{
|
|
//TraceLog.Trace("ILMath.IsCollisionCircleRect circle {0} {1} radius {2} rect {3} {4} length {5} width {6} angle {7}"
|
|
// , circleX, circleY, radius, rectX, rectY, length, width, angle);
|
|
|
|
Vector2IntFloat circlePos = new Vector2IntFloat {x = circleX, y = circleY};
|
|
Vector2IntFloat rectPos = new Vector2IntFloat {x = rectX, y = rectY};
|
|
|
|
//将坐标按矩形中心点旋转
|
|
Vector2IntFloat newCPos = CalcNewPointOnCoordinate(circlePos, rectPos, -1 * angle);
|
|
|
|
int halfLen = length / 2;
|
|
int halfWid = width / 2;
|
|
|
|
//TraceLog.Trace("ILMath.IsCollisionCircleRect newCPos {0} {1} halfLen {2} halfWid {3}",
|
|
// newCPos.x, newCPos.y, halfLen, halfWid);
|
|
|
|
// 圆心所在的位置,分9个区块判断
|
|
if (newCPos.x >= halfLen && newCPos.y >= halfWid)
|
|
{
|
|
// 右上角
|
|
return IsCollisionCircleCircle(newCPos.x, newCPos.y, radius, halfLen, halfWid, 0);
|
|
}
|
|
else if (newCPos.x >= halfLen && newCPos.y <= -halfWid)
|
|
{
|
|
// 右下角
|
|
return IsCollisionCircleCircle(newCPos.x, newCPos.y, radius, halfLen, -halfWid, 0);
|
|
}
|
|
else if (newCPos.x <= -halfLen && newCPos.y <= -halfWid)
|
|
{
|
|
// 左下角
|
|
return IsCollisionCircleCircle(newCPos.x, newCPos.y, radius, -halfLen, -halfWid, 0);
|
|
}
|
|
else if (newCPos.x <= -halfLen && newCPos.y >= halfWid)
|
|
{
|
|
// 左上角
|
|
return IsCollisionCircleCircle(newCPos.x, newCPos.y, radius, -halfLen, halfWid, 0);
|
|
}
|
|
|
|
if (newCPos.x > -halfLen - radius && newCPos.x < halfLen + radius
|
|
&& newCPos.y > -halfWid - radius && newCPos.y < halfWid + radius)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static Vector2IntFloat CalcNewPointOnCoordinate(Vector2IntFloat pos, Vector2IntFloat origin, int angle)
|
|
{
|
|
int sin = ILMath.Sin(angle);
|
|
int cos = ILMath.Cos(angle);
|
|
|
|
int basenum = 1000;//(cos * cos + sin * sin);
|
|
int dx = pos.x - origin.x;
|
|
int dy = pos.y - origin.y;
|
|
|
|
var newPos = new Vector2IntFloat
|
|
{
|
|
x = (cos * dx - sin * dy) / basenum,
|
|
y = (sin * dx + cos * dy) / basenum,
|
|
};
|
|
|
|
//TraceLog.Trace("ILMath.CalcNewPointOnCoordinate angle {0} sin {1} cos {2} basenum {3} dx {4} dy {5} pos {6} {7} origin {8} {9} pos new {10} {11}",
|
|
// angle, sin, cos, basenum, dx, dy, pos.x, pos.y, origin.x, origin.y, newPos.x, newPos.y);
|
|
|
|
return newPos;
|
|
}
|
|
|
|
//判断圆和圆,圆和点之间的位置关系,交集大于0则返回true
|
|
public static bool IsCollisionCircleCircle(int x1, int y1, int radius1, int x2, int y2, int radius2)
|
|
{
|
|
long disX = x1 - x2;
|
|
long disY = y1 - y2;
|
|
long disSquare1 = disX * disX + disY * disY;
|
|
long disRadius = radius1 + radius2;
|
|
long disSquare2 = disRadius * disRadius;
|
|
return disSquare1 < disSquare2;
|
|
}
|
|
|
|
//判断圆是否和扇形碰撞,sx,sy扇形中心,半径,朝向,夹角
|
|
public static bool IsCollisionCircleSector(int cx, int cy, int radius1,
|
|
int sx, int sy, int radius2, int angle, int sectorAngle)
|
|
{
|
|
long dx = cx - sx;
|
|
long dy = cy - sy;
|
|
long dr = radius1 + radius2;
|
|
|
|
//先判断圆的碰撞
|
|
if (dx * dx + dy * dy > dr * dr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//圆心和扇形圆形的角度在夹角内
|
|
int circleAngle = GetAngle(sx, sy, cx, cy);
|
|
if (circleAngle > angle - sectorAngle / 2 && circleAngle < angle + sectorAngle / 2)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (angle - sectorAngle / 2 < 0 && angle + 360 - sectorAngle / 2 < circleAngle && circleAngle < 360)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (angle + sectorAngle / 2 > 360 && angle + sectorAngle / 2 - 360 > circleAngle && circleAngle > 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (radius1 == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int angle1 = angle - sectorAngle / 2;
|
|
int angle2 = angle + sectorAngle / 2;
|
|
|
|
int x1 = sx + ILMath.Cos(angle1) * radius2 / 1000;
|
|
int y1 = sy + ILMath.Sin(angle1) * radius2 / 1000;
|
|
int x2 = sx + ILMath.Cos(angle2) * radius2 / 1000;
|
|
int y2 = sy + ILMath.Sin(angle2) * radius2 / 1000;
|
|
|
|
#if false
|
|
if (IsCircleIntersectLineSegement(cx, cy, radius1, sx, sy, x1, y1))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (IsCircleIntersectLineSegement(cx, cy, radius1, sx, sy, x2, y2))
|
|
{
|
|
return true;
|
|
}
|
|
#else
|
|
if(IsCircleIntersectLine(cx, cy, radius1, sx, sy, x1, y1))
|
|
{
|
|
return true;
|
|
}
|
|
if (IsCircleIntersectLine(cx, cy, radius1, sx, sy, x2, y2))
|
|
{
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
//判断圆是否和线段相交
|
|
//这个有问题,换IsCircleIntersectLine
|
|
public static bool IsCircleIntersectLineSegement(long centerX, long centerY, long radius, long lineStartX,
|
|
long lineStartY, long lineEndX, long lineEndY)
|
|
{
|
|
long centerVectorX = centerX - lineStartX;
|
|
long centerVectorY = centerY - lineStartY;
|
|
long lineVectorX = lineEndX - lineStartX;
|
|
long lineVectorY = lineEndY - lineStartY;
|
|
|
|
// 当线段是点时,判断点是否在圆内
|
|
if (lineVectorX == 0 && lineVectorY == 0)
|
|
{
|
|
long squareLength = centerVectorX * centerVectorX + centerVectorY * centerVectorY;
|
|
return squareLength <= radius * radius;
|
|
}
|
|
|
|
long lineLength = reckon_sqrt(lineVectorX * lineVectorX + lineVectorY * lineVectorY);
|
|
//normalize,单位化
|
|
lineVectorX = lineVectorX / lineLength;
|
|
lineVectorY = lineVectorY / lineLength;
|
|
|
|
// 投影长度,向量A在B上的投影长度 d = (A dot B) / |B|
|
|
long projectionLength = centerVectorX * lineVectorX + centerVectorY * lineVectorY;
|
|
long nearestPointX = 0;
|
|
long nearestPointY = 0;
|
|
if (projectionLength <= 0)
|
|
{
|
|
nearestPointX = lineStartX;
|
|
nearestPointY = lineStartY;
|
|
}
|
|
else if (projectionLength >= lineLength)
|
|
{
|
|
nearestPointX = lineEndX;
|
|
nearestPointY = lineEndY;
|
|
}
|
|
else
|
|
{
|
|
nearestPointX = lineStartX + lineVectorX * projectionLength;
|
|
nearestPointY = lineStartY + lineVectorY * projectionLength;
|
|
}
|
|
|
|
long dx = centerX - nearestPointX;
|
|
long dy = centerY - nearestPointY;
|
|
long dist2 = dx * dx + dy * dy;
|
|
return dist2 <= radius * radius;
|
|
}
|
|
|
|
public static Fixed64Vector2 ClosestPoint(Fixed64Vector2 start, Fixed64Vector2 end, Fixed64Vector2 point)
|
|
{
|
|
Fixed64Vector2 direction = end - start;
|
|
|
|
Fixed64 t = direction.SqrMagnitude;
|
|
if (t == 0) return start;
|
|
|
|
t = FixedMath.Clamp01(Fixed64Vector2.Dot(point - start, direction) / t);
|
|
return start + direction * t;
|
|
}
|
|
|
|
public static bool IsCircleIntersectLine(Fixed64Vector2 start, Fixed64Vector2 end, Fixed64Vector2 center, Fixed64 radius)
|
|
{
|
|
Fixed64 sqrDistance = (ClosestPoint(start, end, center) - center).SqrMagnitude;
|
|
return sqrDistance < radius * radius;
|
|
}
|
|
|
|
public static bool IsCircleIntersectLine(int centerX, int centerY, int radius, int lineStartX, int lineStartY, int lineEndX, int lineEndY)
|
|
{
|
|
Fixed64Vector2 start = new Fixed64Vector2((Fixed64)lineStartX / 1000, (Fixed64)lineStartY / 1000);
|
|
Fixed64Vector2 end = new Fixed64Vector2((Fixed64)lineEndX / 1000, (Fixed64)lineEndY / 1000);
|
|
Fixed64Vector2 center = new Fixed64Vector2((Fixed64)centerX / 1000, (Fixed64)centerY / 1000);
|
|
Fixed64 fradius = (Fixed64)radius / 1000;
|
|
|
|
#if false
|
|
return IsCircleIntersectLine(center.x, center.y, fradius, start, end);
|
|
#else
|
|
return IsCircleIntersectLine(start, end, center,fradius);
|
|
#endif
|
|
|
|
}
|
|
|
|
public static bool IsCircleIntersectLine(Fixed64 x, Fixed64 y, Fixed64 radius, Fixed64Vector2 vStart, Fixed64Vector2 vEnd)
|
|
{
|
|
Fixed64Vector2 vNearest = new Fixed64Vector2(); // 线段上到圆心最近的点
|
|
|
|
Fixed64Vector2 vDis = vEnd - vStart;
|
|
if (vDis.x == 0 && vDis.y == 0)
|
|
{
|
|
vNearest = vStart;
|
|
}
|
|
else
|
|
{
|
|
// 求圆心在直线上的投影点
|
|
Fixed64Vector2 upright;
|
|
{
|
|
|
|
// 直线的长度与方向
|
|
Fixed64 length = Fixed64Vector2.Distance(vStart, vEnd);
|
|
Fixed64Vector2 dir = vDis / length;
|
|
|
|
// 直线法向
|
|
Fixed64Vector2 normal = new Fixed64Vector2(-dir.y, dir.x);
|
|
Fixed64 distance = -(vStart.x * normal.x + vStart.y * normal.y);
|
|
|
|
// 圆心到直线的距离
|
|
Fixed64 disToCenter = normal.x * x + normal.y * y + distance;
|
|
if (disToCenter > radius)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
upright = normal * (-disToCenter);
|
|
upright.x += x;
|
|
upright.y += y;
|
|
|
|
|
|
}
|
|
|
|
|
|
Fixed64 radio;
|
|
if (vDis.x != 0) // 是否为0
|
|
{
|
|
radio = (upright.x - vStart.x) / vDis.x;
|
|
}
|
|
else
|
|
{
|
|
radio = (upright.y - vStart.y) / vDis.y;
|
|
}
|
|
|
|
if (radio < 0)
|
|
{
|
|
vNearest = vStart;
|
|
}
|
|
else if (radio > 1)
|
|
{
|
|
vNearest = vEnd;
|
|
}
|
|
else
|
|
{
|
|
vNearest.x = upright.x;
|
|
vNearest.y = upright.y;
|
|
}
|
|
}
|
|
|
|
|
|
return Fixed64Vector2.DistanceSquared(vNearest, new Fixed64Vector2(x, y)) < radius * radius;
|
|
}
|
|
|
|
public static void BubbleSortList<T>(List<T> list, Func<T,T,int> compare)
|
|
{
|
|
for (int i = list.Count; i > 0; i--)
|
|
{
|
|
for (int j = 0; j < i - 1; j++)
|
|
{
|
|
if (compare(list[j], list[j + 1]) > 0)
|
|
{
|
|
T temp = list[j];
|
|
list[j] = list[j + 1];
|
|
list[j + 1] = temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//预估迭代法
|
|
public static int reckon_sqrt( long x)
|
|
{
|
|
int y;
|
|
|
|
//初始估计值,太大对这个项目也没啥意义了,应该不会用到
|
|
if (x > 4294967296L)
|
|
{
|
|
if (x > 17592186044416) y = 6291456;
|
|
else if (x > 4398046511104) y = 3145728;
|
|
else if (x > 1099511627776) y = 1572864;
|
|
else if (x > 274877906944) y = 786432;
|
|
else if (x > 68719476736) y = 393216;
|
|
else if (x > 17179869184) y = 196608;
|
|
else y = 98304;
|
|
|
|
}
|
|
else if( x > 262144)
|
|
{
|
|
if (x > 1073741824) y = 49152;
|
|
else if (x > 268435456) y = 24576;
|
|
else if (x > 67108864) y = 12288;
|
|
else if (x > 16777216) y = 6144;
|
|
else if (x > 4194304) y = 3072;
|
|
else if (x > 1048576) y = 1536;
|
|
else y = 768;
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
if (x > 65536) y = 384;
|
|
else if (x > 16384) y = 192;
|
|
else if (x > 4096) y = 96;
|
|
else if (x > 1024) y = 48;
|
|
else if (x > 256) y = 24;
|
|
else if (x > 64) y = 12;
|
|
else y = 6;
|
|
}
|
|
|
|
y = (y + (int)(x / y)) >> 1;
|
|
y = (y + (int)(x / y)) >> 1;
|
|
y = (y + (int)(x / y)) >> 1;
|
|
|
|
return y;
|
|
}
|
|
|
|
public static int shift_sqrt(long val)
|
|
{
|
|
long r = 0;
|
|
for (int shift = 0; shift < 64; shift += 2)
|
|
{
|
|
long x = 0x4000000000000000L >> shift;
|
|
|
|
if (x + r <= val)
|
|
{
|
|
val -= x + r;
|
|
r = (r >> 1) | x;
|
|
}
|
|
else
|
|
{
|
|
r >>= 1;
|
|
}
|
|
}
|
|
|
|
//if(r < val) ++r;
|
|
|
|
return (int)r;
|
|
}
|
|
|
|
public static bool IsInCameraView(int[,] viewMat4x4, int posX, int posZ)
|
|
{
|
|
int x = viewMat4x4[0, 0] * posX / 1000 + viewMat4x4[0, 2] * posZ / 1000 + viewMat4x4[0, 3];
|
|
int z = viewMat4x4[2, 0] * posX / 1000 + viewMat4x4[2, 2] * posZ / 1000 + viewMat4x4[2, 3];
|
|
int num = viewMat4x4[3, 0] * posX / 1000 + viewMat4x4[3, 2] * posZ / 1000 + viewMat4x4[3, 3];
|
|
|
|
// 乘以1000来表示小数
|
|
x = x * 1000 / num;
|
|
z = z * 1000 / num;
|
|
|
|
return -1000 <= x && x <= 1000 && -1000 <= z && z <= 1000;
|
|
|
|
//Fixed64[,] fixViewMat = new Fixed64[4,4];
|
|
//for (int i = 0; i < 4; i++)
|
|
//{
|
|
// for (int j = 0; j < 4; j++)
|
|
// {
|
|
// fixViewMat[i, j] = (Fixed64) viewMat4x4[i, j] / 1000;
|
|
// }
|
|
//}
|
|
|
|
//Fixed64 fixPosX = (Fixed64) posX / (Fixed64)1000;
|
|
//Fixed64 fixPosZ = (Fixed64) posZ / (Fixed64)1000;
|
|
|
|
//Fixed64 x1 = fixViewMat[0, 0] * fixPosX + fixViewMat[0, 2] * fixPosZ + fixViewMat[0, 3];
|
|
//Fixed64 z1 = fixViewMat[2, 0] * fixPosX + fixViewMat[2, 2] * fixPosZ + fixViewMat[2, 3];
|
|
//Fixed64 num1 = fixViewMat[3, 0] * fixPosX + fixViewMat[3, 2] * fixPosZ + fixViewMat[3, 3];
|
|
|
|
//x1 = x1 / num1;
|
|
//z1 = z1 / num1;
|
|
}
|
|
|
|
public static bool IsInPolygon(int[,] v, long posX, long posZ)
|
|
{
|
|
long a = (v[1, 0] - v[0, 0]) * (posZ - v[0, 1]) - (v[1, 1] - v[0, 1]) * (posX - v[0, 0]);
|
|
long b = (v[2, 0] - v[1, 0]) * (posZ - v[1, 1]) - (v[2, 1] - v[1, 1]) * (posX - v[1, 0]);
|
|
long c = (v[3, 0] - v[2, 0]) * (posZ - v[2, 1]) - (v[3, 1] - v[2, 1]) * (posX - v[2, 0]);
|
|
long d = (v[0, 0] - v[3, 0]) * (posZ - v[3, 1]) - (v[0, 1] - v[3, 1]) * (posX - v[3, 0]);
|
|
if ((a >= 0 && b >= 0 && c >= 0 && d >= 0) || (a <= 0 && b <= 0 && c <= 0 & d <= 0))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//算立方根
|
|
public static long CalCubeRoot(long num)
|
|
{
|
|
//精度太高了,项目用不到。实测release模式下效率不如下面的二分法,涉及到小数,跨平台还会有问题
|
|
//return (long)Math.Pow((double)num, (double)1 / 3);
|
|
|
|
if (num == 1000000000)
|
|
{
|
|
return 1000;
|
|
}
|
|
long left, right;
|
|
if (num < 1000000000)
|
|
{
|
|
left = 0;
|
|
right = 1000;
|
|
}
|
|
else
|
|
{
|
|
left = 1000;
|
|
right = 2 * left;
|
|
while (right * right * right <= num)
|
|
{
|
|
left *= 2;
|
|
right = 2 * left;
|
|
}
|
|
}
|
|
|
|
while (right - left > 4)
|
|
{
|
|
long mid = left + (right - left) / 2;
|
|
long midCube = mid * mid * mid;
|
|
if (midCube == num)
|
|
{
|
|
return mid;
|
|
}
|
|
if (mid * mid * mid < num)
|
|
{
|
|
left = mid;
|
|
}
|
|
else
|
|
{
|
|
right = mid;
|
|
}
|
|
}
|
|
long res = left;
|
|
for (var i = left + 1; i <= right; ++i)
|
|
{
|
|
if (i * i * i <= num)
|
|
{
|
|
res = i;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
}
|
|
|