22
33public static partial class DsFen
44{
5- private static readonly List < ( int x , int y ) > polygon2 =
6- [
7- new ( 73 , 82 ) , // Left
8- new ( 84 , 93 ) , // Top
9- new ( 101 , 76 ) , // Right
10- new ( 90 , 65 ) , // Bottom
11- ] ;
12- private static readonly List < ( int x , int y ) > polygon1 =
13- [
14- new ( 154 , 163 ) , // Left
15- new ( 165 , 174 ) , // Top
16- new ( 182 , 157 ) , // Right
17- new ( 171 , 146 ) , // Bottom
18- ] ;
19- private const double CenterX = 128.0 ;
20- private const double CenterY = 120.0 ;
5+ public static readonly Polygon polygon2 = new Polygon ( new ( 84 , 93 ) , new ( 101 , 76 ) , new ( 90 , 65 ) , new ( 73 , 82 ) ) ;
6+ public static readonly Polygon polygon1 = new Polygon ( new ( 165 , 174 ) , new ( 182 , 157 ) , new ( 171 , 146 ) , new ( 154 , 163 ) ) ;
217
228 public static string GetFen ( SpawnDto spawn , Commander cmdr , int team )
239 {
2410 var build = CmdrBuildFactory . Create ( cmdr ) ;
2511 if ( build == null ) return string . Empty ;
2612
2713 var polygon = team == 1 ? polygon1 : polygon2 ;
28- var origin = polygon [ 3 ] ; // Bottom point is origin
2914
30- var groundUnits = new Dictionary < ( int x , int y ) , char > ( ) ;
31- var airUnits = new Dictionary < ( int x , int y ) , char > ( ) ;
15+ var groundUnits = new Dictionary < DsPoint , char > ( ) ;
16+ var airUnits = new Dictionary < DsPoint , char > ( ) ;
3217
3318 foreach ( var unit in spawn . Units )
3419 {
@@ -42,26 +27,26 @@ public static string GetFen(SpawnDto spawn, Commander cmdr, int team)
4227 var points = GetPoints ( unit . Poss ) ;
4328 foreach ( var p in points )
4429 {
45- if ( ! IsPointInsideOrOnEdge ( p , team ) )
30+ if ( ! polygon . IsPointInside ( p ) )
4631 {
4732 continue ;
4833 }
49- var grid = RotateNeg45Int ( p ) ;
34+ var grid = polygon . GetNormalizedPoint ( p ) ;
5035 if ( buildOption . IsAir )
5136 airUnits [ grid ] = key ;
5237 else
5338 groundUnits [ grid ] = key ;
5439 }
5540 }
5641
57- string EncodeLayer ( Dictionary < ( int x , int y ) , char > layer )
42+ string EncodeLayer ( Dictionary < DsPoint , char > layer )
5843 {
5944 if ( layer . Count == 0 ) return "" ;
6045
61- int minX = layer . Keys . Min ( p => p . x ) ;
62- int maxX = layer . Keys . Max ( p => p . x ) ;
63- int minY = layer . Keys . Min ( p => p . y ) ;
64- int maxY = layer . Keys . Max ( p => p . y ) ;
46+ int minX = layer . Keys . Min ( p => p . X ) ;
47+ int maxX = layer . Keys . Max ( p => p . X ) ;
48+ int minY = layer . Keys . Min ( p => p . Y ) ;
49+ int maxY = layer . Keys . Max ( p => p . Y ) ;
6550
6651 var rows = new List < string > ( ) ;
6752 for ( int y = minY ; y <= maxY ; y ++ )
@@ -70,7 +55,7 @@ string EncodeLayer(Dictionary<(int x, int y), char> layer)
7055 int empty = 0 ;
7156 for ( int x = minX ; x <= maxX ; x ++ )
7257 {
73- if ( layer . TryGetValue ( ( x , y ) , out char key ) )
58+ if ( layer . TryGetValue ( new ( x , y ) , out char key ) )
7459 {
7560 if ( empty > 0 )
7661 {
@@ -117,17 +102,16 @@ public static void ApplyFen(string fen, SpawnDto spawn, out Commander cmdr, out
117102 if ( build == null ) return ;
118103
119104 var polygon = team == 1 ? polygon1 : polygon2 ;
120- var origin = polygon [ 3 ] ;
121105
122106 var layers = parts [ 1 ] . Split ( '|' ) ;
123107 string groundLayer = layers . Length > 0 ? layers [ 0 ] : "" ;
124108 string airLayer = layers . Length > 1 ? layers [ 1 ] : "" ;
125109
126- ParseLayer ( groundLayer , build , false , spawn , origin ) ;
127- ParseLayer ( airLayer , build , true , spawn , origin ) ;
110+ ParseLayer ( groundLayer , build , false , spawn , polygon ) ;
111+ ParseLayer ( airLayer , build , true , spawn , polygon ) ;
128112 }
129113
130- private static void ParseLayer ( string layer , CmdrBuild build , bool isAir , SpawnDto spawn , ( int x , int y ) origin )
114+ private static void ParseLayer ( string layer , CmdrBuild build , bool isAir , SpawnDto spawn , Polygon polygon )
131115 {
132116 if ( string . IsNullOrWhiteSpace ( layer ) ) return ;
133117
@@ -155,8 +139,8 @@ private static void ParseLayer(string layer, CmdrBuild build, bool isAir, SpawnD
155139 var name = build . GetUnitNameFromKey ( key , isAir , isUpper ) ;
156140 if ( name != null )
157141 {
158- var gridPos = ( x , y ) ;
159- var world = RotatePos45Int ( gridPos ) ;
142+ var gridPos = new DsPoint ( x , y ) ;
143+ var world = polygon . GetDeNormalizedPoint ( gridPos ) ;
160144
161145 var unit = spawn . Units . FirstOrDefault ( u => u . Unit . Name == name ) ;
162146 if ( unit == null )
@@ -167,7 +151,7 @@ private static void ParseLayer(string layer, CmdrBuild build, bool isAir, SpawnD
167151
168152 if ( ! string . IsNullOrEmpty ( unit . Poss ) )
169153 unit . Poss += "," ;
170- unit . Poss += $ "{ world . x } ,{ world . y } ";
154+ unit . Poss += $ "{ world . X } ,{ world . Y } ";
171155 unit . Count ++ ;
172156 }
173157
@@ -177,102 +161,19 @@ private static void ParseLayer(string layer, CmdrBuild build, bool isAir, SpawnD
177161 }
178162 }
179163
180- private static ( double x , double y ) Rotate ( ( int x , int y ) pt , double angleDeg )
181- {
182- double angleRad = angleDeg * Math . PI / 180.0 ;
183- double cos = Math . Cos ( angleRad ) ;
184- double sin = Math . Sin ( angleRad ) ;
185-
186- double dx = pt . x - CenterX ;
187- double dy = pt . y - CenterY ;
188-
189- double x = cos * dx - sin * dy + CenterX ;
190- double y = sin * dx + cos * dy + CenterY ;
191-
192- return ( x , y ) ;
193- }
194-
195- private static ( int x , int y ) RotateNeg45Int ( ( int x , int y ) pt )
196- {
197- var rotated = Rotate ( pt , - 45 ) ;
198- return ( ( int ) Math . Round ( rotated . x ) , ( int ) Math . Round ( rotated . y ) ) ;
199- }
200-
201- private static ( int x , int y ) RotatePos45Int ( ( int x , int y ) pt )
202- {
203- var rotated = Rotate ( pt , + 45 ) ;
204- return ( ( int ) Math . Round ( rotated . x ) , ( int ) Math . Round ( rotated . y ) ) ;
205- }
206-
207- private static List < ( int x , int y ) > GetPoints ( string possString )
164+ public static List < DsPoint > GetPoints ( string possString )
208165 {
209166 if ( string . IsNullOrEmpty ( possString ) )
210167 {
211168 return [ ] ;
212169 }
213170 var stringPoints = possString . Split ( ',' , StringSplitOptions . RemoveEmptyEntries ) ;
214- List < ( int x , int y ) > points = [ ] ;
171+ List < DsPoint > points = [ ] ;
215172 for ( int i = 0 ; i < stringPoints . Length ; i += 2 )
216173 {
217- points . Add ( ( int . Parse ( stringPoints [ i ] ) , int . Parse ( stringPoints [ i + 1 ] ) ) ) ;
174+ points . Add ( new ( int . Parse ( stringPoints [ i ] ) , int . Parse ( stringPoints [ i + 1 ] ) ) ) ;
218175 }
219176 return points ;
220177 }
221178
222- private static bool IsPointInsideOrOnEdge ( ( int x , int y ) p , int team )
223- {
224- var polygon = team == 1 ? polygon1 : polygon2 ;
225- if ( IsPointInPolygon ( p , polygon ) )
226- return true ;
227-
228- for ( int i = 0 ; i < polygon . Count ; i ++ )
229- {
230- if ( IsOnEdge ( p , polygon [ i ] , polygon [ ( i + 1 ) % polygon . Count ] ) )
231- return true ;
232- }
233-
234- return false ;
235- }
236-
237- private static bool IsPointInPolygon ( ( int x , int y ) p , List < ( int x , int y ) > polygon )
238- {
239- int wn = 0 ; // winding number
240- int n = polygon . Count ;
241-
242- for ( int i = 0 ; i < n ; i ++ )
243- {
244- ( int x , int y ) pi = polygon [ i ] ;
245- ( int x , int y ) pj = polygon [ ( i + 1 ) % n ] ;
246-
247- if ( pi . y <= p . y )
248- {
249- if ( pj . y > p . y && IsLeft ( pi , pj , p ) > 0 )
250- wn ++ ;
251- }
252- else
253- {
254- if ( pj . y <= p . y && IsLeft ( pi , pj , p ) < 0 )
255- wn -- ;
256- }
257- }
258-
259- return wn != 0 ;
260- }
261-
262- private static double IsLeft ( ( int x , int y ) p0 , ( int x , int y ) p1 , ( int x , int y ) p2 )
263- {
264- return ( p1 . x - p0 . x ) * ( p2 . y - p0 . y ) - ( p2 . x - p0 . x ) * ( p1 . y - p0 . y ) ;
265- }
266-
267- private static bool IsOnEdge ( ( int x , int y ) p , ( int x , int y ) a , ( int x , int y ) b )
268- {
269- double cross = ( p . y - a . y ) * ( b . x - a . x ) - ( p . x - a . x ) * ( b . y - a . y ) ;
270- if ( Math . Abs ( cross ) > 1e-6 ) return false ;
271-
272- double dot = ( p . x - a . x ) * ( b . x - a . x ) + ( p . y - a . y ) * ( b . y - a . y ) ;
273- if ( dot < 0 ) return false ;
274-
275- double lenSq = ( b . x - a . x ) * ( b . x - a . x ) + ( b . y - a . y ) * ( b . y - a . y ) ;
276- return dot <= lenSq ;
277- }
278179}
0 commit comments