src/hcode/mech.lostracer.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mech.h"
#include "btmacros.h"

Include dependency graph for mech.lostracer.c:

Go to the source code of this file.

Defines

#define DEG60   1.0471976
#define DEG30   0.5235988
#define ROOT3   1.7320508
#define TRACESCALEMAP   1
#define Store_Hex(store_x, store_y)
#define Store_BestOf(x1, y1, x2, y2)
#define LOS_MapCoordToRealCoord(x, y, cx, cy)

Enumerations

enum  hexdir {
  N, NE, SE, S,
  SW, NW
}

Functions

static void GetAdjHex (int currx, int curry, int nexthex, int *x, int *y)
int TraceLOS (MAP *map, int ax, int ay, int bx, int by, lostrace_info **result)


Define Documentation

#define DEG30   0.5235988

Definition at line 148 of file mech.lostracer.c.

Referenced by TraceLOS().

#define DEG60   1.0471976

Definition at line 147 of file mech.lostracer.c.

Referenced by TraceLOS().

#define LOS_MapCoordToRealCoord ( x,
y,
cx,
cy   ) 

Value:

do { cx = (float)x * ROOT3 / 2 * TRACESCALEMAP; \
  cy = ((float)y - 0.5*(x%2))*TRACESCALEMAP;} while (0)

Definition at line 170 of file mech.lostracer.c.

Referenced by TraceLOS().

#define ROOT3   1.7320508

Definition at line 149 of file mech.lostracer.c.

#define Store_BestOf ( x1,
y1,
x2,
y2   ) 

Value:

if ( ((x1) < 0) || ((x1) >= map->map_width) || \
     ((y1) < 0) || ((y1) >= map->map_height) ) \
    { Store_Hex((x2), (y2)); } \
else if ( ((x2) < 0) || ((x2) >= map->map_width) || \
          ((y2) < 0) || ((y2) >= map->map_height) ) \
       { Store_Hex((x1), (y1)); }\
else if ((Elevation(map,(x1),(y1))) > (Elevation(map, (x2), (y2)))) \
    { Store_Hex((x1),(y1)); } \
else { Store_Hex((x2),(y2)); }

Definition at line 159 of file mech.lostracer.c.

Referenced by TraceLOS().

#define Store_Hex ( store_x,
store_y   ) 

Value:

do { found_coords[found_count].x = store_x; \
     found_coords[found_count++].y = store_y; } \
while (0)

Definition at line 154 of file mech.lostracer.c.

Referenced by TraceLOS().

#define TRACESCALEMAP   1

Definition at line 150 of file mech.lostracer.c.

Referenced by TraceLOS().


Enumeration Type Documentation

enum hexdir

Enumerator:
N 
NE 
SE 
S 
SW 
NW 

Definition at line 152 of file mech.lostracer.c.

00152 { N, NE, SE, S, SW, NW } hexdir;


Function Documentation

static void GetAdjHex ( int  currx,
int  curry,
int  nexthex,
int *  x,
int *  y 
) [static]

Definition at line 174 of file mech.lostracer.c.

References N, NE, NW, S, SE, and SW.

Referenced by TraceLOS().

00175 {
00176         switch (nexthex) {
00177         case N:
00178                 *x = currx;
00179                 *y = curry - 1;
00180                 break;
00181         case NE:
00182                 *x = currx + 1;
00183                 *y = curry - (currx % 2);
00184                 break;
00185         case SE:
00186                 *x = currx + 1;
00187                 *y = curry - (currx % 2) + 1;
00188                 break;
00189         case S:
00190                 *x = currx;
00191                 *y = curry + 1;
00192                 break;
00193         case SW:
00194                 *x = currx - 1;
00195                 *y = curry - (currx % 2) + 1;
00196                 break;
00197         case NW:
00198                 *x = currx - 1;
00199                 *y = curry - (currx % 2);
00200                 break;
00201         default:                                        /* Mostly there to satisfy gcc */
00202                 fprintf(stderr, "XXX ARGH: TraceLos doesn't know where to go!\n");
00203                 *x = currx + 1;                 /* Just grab some values that aren't x/y */
00204                 *y = curry + 1;                 /* so we can break out of the loop */
00205         }
00206 }

int TraceLOS ( MAP map,
int  ax,
int  ay,
int  bx,
int  by,
lostrace_info **  result 
)

Definition at line 208 of file mech.lostracer.c.

References DEG30, DEG60, GetAdjHex(), LOS_MapCoordToRealCoord, N, NW, ROOT3, Store_BestOf, Store_Hex, and TRACESCALEMAP.

00210 {
00211 
00212         int i;                                          /* Generic counter */
00213         float acx, acy, bcx, bcy;       /* endpoints CARTESIAN coords */
00214         float currcx, currcy;           /* current hex CARTESIAN coords */
00215         int currx, curry;                       /* current hex being worked from */
00216         int nextx, nexty;                       /* x & y coords of next hex */
00217         int bestx = 0, besty = 0;       /* best found so far */
00218         int lastx, lasty;                       /* Holding place for final intervening hex */
00219         int xmul, ymul;                         /* Used in 30/150/210/330 special case */
00220         hexdir nexthex;                         /* potential next hex being examined */
00221         float nextcx, nextcy;           /* Next hex's CARTESIAN coords */
00222         float slope;                            /* slope of line */
00223         float uangle;                           /* angle of line (in STD CARTESIAN FORM!) */
00224         float sinu;                                     /* sin of -uangle */
00225         float cosu;                                     /* cos of same */
00226         float liney;                            /* TRANSFORMED y coord of the line */
00227         float tempangle;                        /* temporary uangle used for effrad calc */
00228         float effrad;                           /* effective radius of hex */
00229         float currdist;                         /* distance along line of current hex */
00230         float nextdist;                         /* distance along the line of potential hex */
00231         float bestdist;                         /* "best" (not furthest) distance tried */
00232         float enddist;                          /* distance along at end of line */
00233         static lostrace_info found_coords[4000];
00234         int found_count = 0;
00235 
00236         /* Before doing anything, let's check for special circumstances, this */
00237         /* means vertical lines (which work using the current code, but depend */
00238         /* on atan returning proper vaules for atan(-Inf) -- which is probably */
00239         /* slow and may break on non-ANSI systems; and also lines at 30, 90 */
00240         /* etc.. degrees which contain 'ties' between hexes.  FASA rules here */
00241         /* say that the 'best' hex for the defender (the one that breaks LOS, */
00242         /* or gives a greater BTH penalty) should be used. */
00243 
00244         /* THE base case */
00245         if((ax == bx) && (ay == by)) {
00246                 Store_Hex(bx, by);
00247                 *result = found_coords;
00248                 return found_count;
00249         }
00250         /* Is it vertical? */
00251         if(ax == bx) {
00252                 if(ay > by)
00253                         for(i = ay - 1; i > by; i--)
00254                                 Store_Hex(ax, i);
00255                 else
00256                         for(i = ay + 1; i < by; i++)
00257                                 Store_Hex(ax, i);
00258                 Store_Hex(bx, by);
00259                 *result = found_coords;
00260                 return found_count;
00261         }
00262 
00263         /* Does it lie along a 90 degree 'tie' direction? */
00264         /* IF(even-number-of-cols apart AND same-y-coord) */
00265         if(!((bx - ax) % 2) && ay == by) {
00266                 currx = ax;
00267                 i = bx > ax ? 1 : -1;
00268                 while (currx != bx) {
00269                         /* Do best of (currx+1,by-currx%2)   */
00270                         /*         or (currx+1,by-currx%2+1) */
00271                         Store_BestOf(currx + 1 * i, by - currx % 2, currx + 1 * i,
00272                                                  by - currx % 2 + 1);
00273 
00274                         if(currx != bx)
00275                                 Store_Hex(currx + 2 * i, by);
00276 
00277                         currx += 2 * i;
00278                 }
00279 
00280 /*      Store_Hex(bx,by); */
00281                 *result = found_coords;
00282                 return found_count;
00283         }
00284 
00285         /* Does it lie along a 30, 150, 210, 330 degree 'tie' direction? */
00286         /* This expression is messy, but it just means that a hex is along */
00287         /* 30 degrees if the y distance is (the integer part of) 3/2 */
00288         /* times the x distance, plus 1 if the x difference is odd, AND */
00289         /* the original hex was in an even column and heads in the +y  */
00290         /* direction, or odd and goes -y.  It works, try it :) */
00291         if(abs(by - ay) ==
00292            (3 * abs(bx - ax) / 2) + abs((bx - ax) % 2) * abs((by <
00293                                                                                                                   ay) ? (ax %
00294                                                                                                                                  2) : (1 -
00295                                                                                                                                            ax %
00296                                                                                                                                            2))) {
00297 
00298                 /* First get the x and y 'multipliers' -- either 1 or -1 */
00299                 /* they determine the direction of the movement */
00300                 if(bx > ax)
00301                         if(by > ay) {
00302                                 xmul = 1;
00303                                 ymul = 1;
00304                         } else {
00305                                 xmul = 1;
00306                                 ymul = -1;
00307                 } else if(by > ay) {
00308                         xmul = -1;
00309                         ymul = 1;
00310                 } else {
00311                         xmul = -1;
00312                         ymul = -1;
00313                 }
00314 
00315                 currx = ax;
00316                 curry = ay;
00317                 while ((currx != bx) && (curry != by)) {
00318 
00319                         Store_BestOf(currx, curry + ymul, currx + xmul,
00320                                                  ymul ==
00321                                                  1 ? curry + 1 - currx % 2 : curry - currx % 2);
00322 
00323                         curry += (ymul == 1) ? (2 - currx % 2) : (-1 - currx % 2);
00324                         currx += xmul;
00325 
00326                         if(currx == bx && curry == by)
00327                                 continue;
00328 
00329                         Store_Hex(currx, curry);
00330                 }
00331                 Store_Hex(currx, curry);
00332                 *result = found_coords;
00333                 return found_count;
00334         }
00335 
00336 /****************************************************************************/
00337 
00338 /****  OK, now we know it's not a special case ******************************/
00339 
00340 /****************************************************************************/
00341 
00342 /* First get the necessary constants set up */
00343 
00344         LOS_MapCoordToRealCoord(ax, ay, acx, acy);
00345         LOS_MapCoordToRealCoord(bx, by, bcx, bcy);
00346 
00347         slope = (float) (acy - bcy) / (float) (acx - bcx);
00348 
00349         uangle = -atan(slope);
00350 
00351         sinu = sin(uangle);
00352         cosu = cos(uangle);
00353 
00354         liney = acx * sinu + acy * cosu;        /* we could just as */
00355         /* correctly use bx, by */
00356 
00357         enddist = bcx * cosu - bcy * sinu;
00358 
00359         tempangle = fabs(uangle);
00360         while (tempangle > DEG60)
00361                 tempangle -= DEG60;
00362         effrad = cos(tempangle - DEG30) * TRACESCALEMAP / ROOT3;
00363 
00364         /*****************************************************************/
00365 
00368         /*****************************************************************/
00369 
00370         currx = ax;
00371         curry = ay;
00372         LOS_MapCoordToRealCoord(currx, curry, currcx, currcy);
00373         currdist = currcx * cosu - currcy * sinu;
00374         bestdist = enddist;                     /* set this to the endpoint, the worst */
00375         /* possible point to go to  */
00376 
00377         while (!(currx == bx && curry == by)) {
00378 
00379                 for(nexthex = N; nexthex <= NW; nexthex++) {
00380 
00381                         GetAdjHex(currx, curry, nexthex, &nextx, &nexty);
00382                         LOS_MapCoordToRealCoord(nextx, nexty, nextcx, nextcy);
00383 
00384                         /* Is it on the line? */
00385                         if(fabs((nextcx * sinu + nextcy * cosu) - liney) > effrad)
00386                                 continue;
00387 
00388                         /* Where is it?  Find the transformed x coord */
00389                         nextdist = nextcx * cosu - nextcy * sinu;
00390 
00391                         /* is it forward of the current hex? */
00392                         if(fabs(enddist - nextdist) > fabs(enddist - currdist))
00393                                 continue;
00394 
00395                         /* Is it better than what we have? */
00396                         if(fabs(enddist - nextdist) >= fabs(enddist - bestdist)) {
00397                                 bestdist = nextdist;
00398                                 bestx = nextx;
00399                                 besty = nexty;
00400                         }
00401                 }
00402 
00403                 if(bestx == bx && besty == by) {        /* If we've found the last hex, record */
00404                         lastx = currx;          /* the current hex as the last */
00405                         lasty = curry;          /* intervening hex, save currx/y, */
00406                         currx = bestx;          /* and jump to the end of the loop */
00407                         curry = besty;
00408                         continue;
00409                 }
00410 
00411                 /* ********************************************************* */
00412                 /* HERE is where you put the test code for intervening hexes */
00413                 /* ********************************************************* */
00414                 Store_Hex(bestx, besty);
00415                 /* ********************************************************* */
00416 
00417                 currx = bestx;                  /* Reset the curr hex for the next iteration */
00418                 curry = besty;
00419                 currdist = bestdist;
00420                 bestdist = enddist;             /* reset to worst possible value */
00421 
00422         }
00423 
00424         /* **************************************************** */
00425         /* HERE is where you put the test code for the LAST hex */
00426         /* **************************************************** */
00427         Store_Hex(currx, curry);
00428         /* ********************************************************* */
00429         *result = found_coords;
00430         return found_count;
00431 }


Generated on Mon May 28 04:25:45 2007 for BattletechMUX by  doxygen 1.4.7