home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / CIS_GAME.ARJ / QMAPS1.THD < prev    next >
Text File  |  1993-06-24  |  42KB  |  856 lines

  1. ______________________ Subj: Globe Surface Modelling ______________________
  2.  
  3. Fm: Eric J. Floehr 70003,442                   # 186418 
  4. To: All                                        Date: 10-Jul-92  14:46:58
  5.  
  6. Hello,
  7.  
  8. The discussion about mapping a rectangular surface to a globe representation
  9. on the screen got me thinking that this forum might be a good place to ask a
  10. question I have.  You all seem very knowledgeable and could probably answer
  11. this question! 
  12.  
  13. Basically, I have been working on a plate tectonic model (was inspired by a
  14. program for Xwindows by Dave Allen).  The problem is, that unlike Allen's
  15. model, which uses a rectangular grid, I would like my model to work on a
  16. representation of the surface of a sphere.  This rules out any rectangular
  17. array, because each square would not represent an equal area on the sphere. 
  18. And, no "wrapping" rules could be easily constructed.
  19. I know I will need a custom structure, perhaps triangles, with functions to
  20. manipulate a surface or mesh of triangles (ie. each "square" only has 3
  21. shared sides instead of four, which rules out using a standard 2d array).
  22.  
  23. Anyway, I need to figure out exactly what "mesh" can be used to create an
  24. acurate representation within the computer of the surface of a sphere, with
  25. each "square" of equal area?  Once I have that, I can use the mesh to create
  26. a standard projection to actually present the mesh on the screen.
  27.  
  28. Any insights, pointers, or references?
  29.  
  30. Thanks in advance,
  31. Eric
  32. ...........................................................................
  33.  
  34. Fm: Mark Betz/GD SL 76605,2346                 # 187183 
  35. To: Eric J. Floehr 70003,442 (X)               Date: 12-Jul-92  20:47:15
  36.  
  37. Hi, Eric. I'm not the geometry ace around here, but it seems pretty clear
  38. from the outset that you won't be able to use rectangles. Some sort of
  39. triangular structure could be used, as in a geodesic dome. That would
  40. probably be the simplest structure in terms of vertices that need to be
  41. plotted. 
  42.  
  43. I guess we probably need to know more about what you're doing. You said a
  44. "plate tectonics model". I assume you're carving up the surface of the sphere
  45. into plates, and then modeling the forces between them.
  46.  
  47.                                                         --Mark
  48. ...........................................................................
  49.  
  50. Fm: Eric J. Floehr 70003,442                   # 187382 
  51. To: Mark Betz/GD SL 76605,2346 (X)             Date: 13-Jul-92  11:45:17
  52.  
  53. Mark,
  54.  
  55. Thanks for the reply!  I hadn't thought about the geodesic dome model, but I
  56. will definately look at how that is constructed to see if it will work as a
  57. structure for it.  You are right, rectangles won't work, but make things a
  58. lot easier! Both in manipulation and display.  I think that is one reason I
  59. am having so much trouble finding any articles or information on using
  60. something other than rectangles!  I've looked for info on how the weather
  61. service, etc. do thier global models, but none of the books went into any
  62. detail. 
  63.  
  64. As for my model, it is going to be a plate tectonic simulator.  It is not
  65. going to be rigorous in that it will use "realistic" modeling: ie. modelling
  66. the convection processes in the mantle, mostly because we know so little
  67. about it.  But it will take into account most of the major known processes
  68. that change the earth: the creation of faults, rift valleys, mountains, etc. 
  69. Since no one really knows, say, why a plate splits, etc. that will be fairly
  70. random but modelled in a "realistic" manner.  For example, when a plate
  71. splits, the two plates will always rotate about a point on neither (usually)
  72. plate that can be intersected by the fault line.  This behavior will then
  73. cause other plates to run into each other, or slide past each other.  The
  74. ultimate purpose of this project is not only for obvious educational
  75. purposes, but for those that may wish to "create worlds" with a more
  76. realistic flavor and more "history" than a fractal-based creation.
  77.  
  78. The next step in the process would be climactic determinations (ie. when,
  79. where, and why an area of land would be a desert, etc.)  But that is a ways
  80. off!
  81.  
  82. Again, thanks for your help!
  83.  
  84. -Eric
  85. ...........................................................................
  86.  
  87. Fm: Eric J. Floehr 70003,442                   # 188201 
  88. To: Mark Betz/GD SL 76605,2346 (X)             Date: 15-Jul-92  22:35:33
  89.  
  90. Mark,
  91.  
  92. I've had a chance to think about the problem of creating a globe structure in
  93. the computer and I've come up with a solution.  I thought about overlaying
  94. triangles and other regular shapes unto a sphere, and thought about the idea
  95. of geodesics.  However, the problem with that is that they aren't squares
  96. (and as you and I know, square representation is much simpler!), and that the
  97. pattern itself would be irregular (ie. you would have to include pointer
  98. information, unlike using a rectangular array where its position determines
  99. its neighbors).  Then of course, one would need an identifier to each
  100. triangle.  Needless to say it wouldn't be an elegant solution.
  101.  
  102. But while I was thinking about how one would map a point to a particular area
  103. (like a triangle), I thought about how we do it on our globe: latitude and
  104. longitude.  Obviously, the problem with lat and long is that while each lat
  105. division occurs at an equal spacing, the longitudes spread out from the pole
  106. to the equator.
  107.  
  108. So think of this:  squares can be used to ensircle an area around the
  109. equator, and around the meridian.  If we want to be neat, we could choose the
  110. number of squares such that a square sits over both poles.  Thus, we choose
  111. 4, 8, 16, 32, etc. squares to do this.  The squares would not be distorted,
  112. and each square would have an equal area.  Now, the line through the centers
  113. of each square on the equator forms the 0 latitude.  The line through the
  114. first square above the equator on the meridian forms latitude 1, etc.  We
  115. could then string these squares along each latitude, squeezing or streching
  116. each latitude to create an integer number of squares (which would only
  117. incorporate minor and acceptable distortion).
  118.  
  119. Formally, the number of squares for a given latitude can be found by:
  120.  
  121. (# squares around eq. & meridian) * cos((360 / # squares) * lat. line)
  122.  
  123. For example, if we place 16 squares around the meridian and equator:
  124.  
  125. N. Pole:  1 square
  126. Lat. 3 :  6
  127. Lat. 2 : 11
  128. Lat. 1 : 15
  129. Equator: 16
  130. Lat. -1: 15
  131. Lat. -2: 11
  132. Lat. -3:  6
  133. S. Pole:  1
  134.  
  135. Then, the only mapping (and it can be a mathmatical rather than physical
  136. mapping) is from one lat. to another.  From long. to long. there is only a
  137. standard array.
  138.  
  139. Obviously there is some error, since we will end up with "gaps" where
  140. there is a non integer number of squares needed to fill at lat..  These gaps
  141. however, average out.  Look at the chart for the remarkable closeness of fit
  142. of this model:
  143.  
  144. Circum is the number of squares around the equator and meridian, EF is my
  145. method, and Real is the actual surface area for a sphere of given
  146. circumfrence, and then the error.
  147.  
  148. Circum:    32  EF:         328  Real:        325.949  Error: 0.6291397%
  149. Circum:    64  EF:        1302  Real:       1303.797  Error: 0.1378507%
  150. Circum:   128  EF:        5218  Real:       5215.189  Error: 0.0538969%
  151. Circum:   256  EF:       20860  Real:      20860.757  Error: 0.0036274%
  152. Circum:   512  EF:       83442  Real:      83443.027  Error: 0.0012305%
  153. Circum:  1024  EF:      333772  Real:     333772.107  Error: 0.0000321%
  154. Circum:  2048  EF:     1335088  Real:    1335088.429  Error: 0.0000321%
  155. Circum:  4096  EF:     5340340  Real:    5340353.715  Error: 0.0002568%
  156. Circum:  8192  EF:    21361402  Real:   21361414.862  Error: 0.0000602%
  157. Circum: 16384  EF:    85445714  Real:   85445659.447  Error: 0.0000638%
  158. Circum: 32768  EF:   341782596  Real:  341782637.787  Error: 0.0000122%
  159. Circum: 65536  EF:  1367130648  Real: 1367130551.148  Error: 0.0000071%
  160.  
  161. Obviously, a 1024 circumfrence is the last practical one (326K is quite large
  162. for an array!), and the error is 3/100,000 of a percent.
  163.  
  164. See any flaws?  I haven't but I could be wrong.  Let me know what you think!
  165.  
  166. Thanks,
  167. -Eric
  168. ...........................................................................
  169.  
  170. Fm: Mark Betz/GD SL 76605,2346                 # 188425 
  171. To: Eric J. Floehr 70003,442                   Date: 16-Jul-92  17:26:59
  172.  
  173. Hi, Eric. I have to be careful here, because I'm more than a bit out of my
  174. league. However, my impression is that you aren't modeling a sphere, but
  175. rather a "wedding cake" arrangement of circular solids. Imagine taking a
  176. cross section of your world bisecting the north and south poles...
  177.                                 __
  178.                              __|__|__
  179.                           __|__|__|__|__
  180.                          |__|__|__|__|__|
  181.                             |__|__|__|
  182.                                |__|
  183.  
  184. As you point out, the result is sort of analogous to aliasing in a digitized
  185. image: you lose some information. How much depends on the size of your
  186. squares. If the resulting resolution is enough for your purposes, then you're
  187. ok. 
  188.  
  189. Another possibility is representing the surface of the globe as a spherical
  190. array of contiguous points in three-space. Given one point, the diameter of
  191. the sphere, and probably some other esoterics of which I'm ignorant, you
  192. could calculate the position of the next point in any direction.
  193.  
  194.                                                       --Mark
  195. ...........................................................................
  196.  
  197. Fm: Eric J. Floehr 70003,442                   # 188550 
  198. To: Mark Betz/GD SL 76605,2346 (X)             Date: 16-Jul-92  23:32:50
  199.  
  200. Mark,
  201.  
  202. Whoops!  It seems I didn't really make myself clear, and I appologize. 
  203. Actually the idea is not one of cubes, but one of squares.  Remember that I
  204. am trying to model the surface of the sphere, and have no interest in either
  205. its exterior or interior.  Let me explain my model by using a little more
  206. practical example, and hopefully I can articulate this a little better:
  207.  
  208. Say you have a sphere, that you want to glue squares onto (for whatever
  209. reason) So you cut out squares of the same size, get your glue out, and go to
  210. work.  The easiest and most logical place to start would be the equator. 
  211. Lets say we manage it so that it takes exactly 16 squares to go completely
  212. around equator.  There will be some slight overlap since a flat square needs
  213. to fit on a curving surface, but it is minimal and can be ignored.  We do the
  214. same with the meridian, so we have two "equators", one horizontal and one
  215. vertical, intersecting exactly at two places.  Then, since latitude lines
  216. always have equal spacing but longitude lines don't (they are the widest at
  217. the equator and converge to a single point at the poles), we need to start
  218. covering the globe in latitudinal "strips".  So start gluing squares from the
  219. square directly above the equator on the meridian.  As you glue around the
  220. sphere, you will find that after you place your 14th square, there will be
  221. room for about 78% of a 15th square, so you squish the squares so you can fit
  222. 15 squares in.  Then, for the square on the meridian above both those lines,
  223. you'll end up with 30% of a square gap after the 11th square, so you'd need
  224. to stretch them a little.  Then, for the next, you'll end up placing 6
  225. squares, with about a 12% of a square gap.  Then you'll have the poles. 
  226. Pulling the glued squares from the sphere you'd end up with "strips of
  227. squares" like: 
  228.  __
  229. |__|__ __ __ __ __
  230. |__|__|__|__|__|__|__ __ __ __ __
  231. |__|__|__|__|__|__|__|__|__|__|__|__ __ __ __
  232. |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__
  233. |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|
  234. |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|
  235. |__|__|__|__|__|__|__|__|__|__|__|
  236. |__|__|__|__|__|__|
  237. |__|
  238.  
  239. Obviously, there will be a lot of overlap of the squares on the curves
  240. surface, but this decreases as each square becomes less of a percentage of
  241. the surface area.  Is this clearer?  Let me know if it isn't.
  242.  
  243. As for projection: a Mercator projection becomes simple:  just take the
  244. graphic above, and stretch each strip horizontally, stretching each square
  245. equally, until they all match up.  Something like:
  246.  
  247. _______________________________________________
  248. |_______ _______ _______ _______ _______ _______|
  249. |___ ___|____ __|____ __|_ ___ _|_ ____ |__ ____|
  250. |___|___|____|___|___|____|___|___|____|___|____|
  251. |___|__|__|__|__|___|__|__|__|__|___|__|__|__|__|
  252. |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|
  253. |___|__|__|__|__|___|__|__|__|__|___|__|__|__|__|
  254. |___|___|____|___|___|____|___|___|____|___|____|
  255. |_______|_______|_______|_______|_______|_______|
  256. |_______________________________________________|
  257.  
  258. And, in fact this is how the "mapping" works in going from one latitude to
  259. another: 16 squares at the equator mapped to 15 at latitude 1, 15 mapped to
  260. 11, etc.
  261.  
  262. Then, of course, in the computer each strip is modelled as a 1D array of say
  263. integers, so each square can then contain an altitude, or some other info.
  264.  
  265. -Eric
  266. ...........................................................................
  267.  
  268. Fm: Mark Betz/GD SL 76605,2346                 # 188579 
  269. To: Eric J. Floehr 70003,442 (X)               Date: 17-Jul-92  00:26:54
  270.  
  271. Hi, Eric. That was a better explanation ( the drawings don't hurt <g> ), but
  272. I think I basically had it the first time. It still looks to me like there's
  273. a problem with the model. Since you've tried to make your concept clearer,
  274. I'll try to do the same for my objection. You've compensated for the varying
  275. diameter of a sphere at different latitudes using varying numbers of squares.
  276. Indeed, you end up with the right value for the circumference of the sphere
  277. at _some_ point along the y-axis of each square. But the problem is that
  278. squares won't map to a sphere. They have to be trapezoids. If you take a set
  279. of your squares as a strip wrapped around the sphere at a given latitude it's
  280. clearer: the circumference of the strip is the same at min and max y, making
  281. it a cylinder, not a section of a sphere. This is what I was trying to
  282. illustrate with the drawing in my reply. To me this seems analogous to the
  283. aliasing that takes place when a smooth curve is rendered into a specific
  284. display resolution. Since you can't represent the smooth, curved surface of a
  285. sphere using squares, what you end up with is a chunky model of a sphere
  286. constructed of cylindrical solids stacked one on top of another. The
  287. resolution of the model will depend on the number and size of the squares. 
  288.                                                         --Mark
  289. ...........................................................................
  290.  
  291. Fm: Eric J. Floehr 70003,442                   # 188710 
  292. To: Mark Betz/GD SL 76605,2346 (X)             Date: 17-Jul-92  12:44:01
  293.  
  294. Mark,
  295.  
  296. Those ASCII drawings sure are tough to make though! <G>  OK, I understand
  297. your point about the overlap, and you are right.  For example, using our 16
  298. square circumfrence model, the circumfrence through the middle of the squares
  299. on the meridian directly above the equator is 14.78 to which we fit 15
  300. squares.  However, the circumfrence at the bottom edge of the squares is
  301. 15.69 and at the top it is 13.30 squares.  In other words we would need to
  302. stretch out the bottoms and squish the tops, creating a trapezoidal
  303. structure, rather than a square.  This becomes worse at the pole where the
  304. median is 6.12, but the bottoms are 8.89 and the tops are 3.12 squares.  Do I
  305. understand your argument correctly?  I take your point, and perhaps I was a
  306. little sloppy in my use of geometric figures :)   Saying I use squares and
  307. stretch them and squeeze them to fit is that same as saying I use trapezoids
  308. and stretch and squeeze them a little less.  Physically this matters, but
  309. conceptually it doesn't.  An string of objects around the latitude can be
  310. squares or trapezoids, or better yet a trapezoid that resides in sphere-space
  311. rather than in Euclidean flat-space, the only thing that matters is that the
  312. model must exactly model the sphere when the number of objects goes to
  313. infinity, and that at coarse resolutions, the objects' areas sufficiently
  314. approximate the sphere's surface.  So long as our squares in our model have
  315. an area of 1, it doesn't matter how it gets that area, and you are right in
  316. saying that it would better get that area (and in fact can only get that
  317. area) if the objects are modelled more closely to trapezoids than to squares.
  318.  
  319. I think we were both dancing around the same point on this issue!
  320.  
  321. As far as your second issue, I think I understand better what you are getting
  322. at, but I dunno.  But let me make this comment.  We need to make the
  323. distiction between Euclidean flat geometry and sphere (what is the name,
  324. Lympanov?) geometry because they are different and irreconcilable.  That is
  325. why we can never convert exactly between the 2D space of the surface of a
  326. sphere and the 2D space of a flat plane.  My model must reside in
  327. sphere-space, not in flat-space, and therefore the only aliasing done is the
  328. same that is done when converting a space with infinate points into a finite
  329. representation. And you can never ever get around that.
  330.  
  331. Thanks for your input and suggestions, they have really helped me.  I hope we
  332. can continue this conversation.
  333.  
  334. -Eric
  335. ...........................................................................
  336.  
  337. Fm: Mark Betz/GD SL 76605,2346                 # 188779 
  338. To: Eric J. Floehr 70003,442 (X)               Date: 17-Jul-92  17:40:37
  339.  
  340. Yep, that's basically what I'm saying. The second "issue" wasn't really an
  341. issue, but rather an attempt at an analogous explanation. If you use squares
  342. to fit the surface of a sphere, you will only be able to approximate the true
  343. shape of it. Similarly a curve cannot be perfectly rendered in pixels. In
  344. this case the pixels are analogous to your squares. The larger the pixels,
  345. the less true the curve; the larger the squares, the less your model will
  346. resemble the true surface of a sphere (which was, after all, Euclid's "most
  347. perfect solid" <g>). 
  348.  
  349. Using trapezoids will yield the same effect, but you will be able to
  350. construct a truer model.
  351.  
  352.                                                         --Mark
  353. ...........................................................................
  354.  
  355. Fm: Eric J. Floehr 70003,442                   # 188799 
  356. To: Mark Betz/GD SL 76605,2346 (X)             Date: 17-Jul-92  18:22:53
  357.  
  358. Mark,
  359.  
  360. Its great that we have finally come to terms! <G>  I intend to dabble with
  361. some implementations this weekend and see what I can come up with.  Once I
  362. have the "globe engine", it will be easy to use it for many applications, as
  363. opposed to integrating it with the tectonic simulator, where it can't be used
  364. again.  Of course, then the next part is actually creating the simulation,
  365. which is a different story!  (I wonder how I could relate the tectonic sim to
  366. a game to make it more appropriate for this section?  Escape the Earthquake,
  367. Venture to the Volcano, Find the Fault? :) ).
  368.  
  369. -Eric
  370. ...........................................................................
  371.  
  372. Fm: Jesse Montrose 76646,3302                  # 188705 
  373. To: Eric J. Floehr 70003,442 (X)               Date: 17-Jul-92  12:10:43
  374.  
  375. Eric,
  376.  
  377. > We could then string these squares along each latitude, squeezing or
  378. streching each latitude to create an integer number of squares (which would
  379. only incorporate minor and acceptable distortion).
  380.  
  381.      Don't forget that your "squares" are not at all square once you get off
  382. the equator and meridian.  The closer you get to a pole, the greater the
  383. difference between the bottom & top widths of the shape.  I call it a shape,
  384. because it won't even be a trapezoid, the sides are curved.
  385.  
  386.         I don't think you should give up on the geodesic model.  You could
  387. still use relatively simple arrays, instead of pointers:
  388.                 
  389.         (just imagine these are real triangles [g])
  390.  
  391. equator vector:     /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
  392. vector 1      : \/\/\/\/\/\/\/\/\/\/\/\/\/\/     (a little shorter)
  393. vector 2      : /\/\/\/\/\/\/\/\/\/\/\/   (etc..)
  394.         .
  395.         .
  396.         .
  397. pole vector   : \/\/\
  398.  
  399. For any given triangle, two of it's neighbors will be next to it on the
  400. vector, and the third is just a simple percentage calculation into the
  401. adjacent vector.  If it's too jagged, you can just add  more triangles, until
  402. you can't see the jags anymore... [g] 
  403. ...........................................................................
  404.  
  405. Fm: Eric J. Floehr 70003,442                   # 188712 
  406. To: Jesse Montrose 76646,3302                  Date: 17-Jul-92  12:52:16
  407.  
  408. Jesse,
  409.  
  410. See my latest response to Mark on that.  Basically you are right, but it
  411. doesn't matter what the actual shape is (within reason) so long as its area
  412. in sphere-space is 1.
  413.  
  414. Thanks for your comments, and I hope to talk with you soon.
  415.  
  416. -Eric
  417.  
  418. ______________________________ Subj: Hex Maps ______________________________
  419.  
  420. Fm: William D. Vaughn 74720,1246               # 308941 
  421. To: all                                        Date: 05-Mar-93  22:12:41
  422.  
  423. Can anyone give me some tips on representing (in C or C++) a hex (hexagon)
  424. map sheet?  I would need to determine the range between two hexes and
  425. determine which hexes fall between two hexes (line of sight).
  426.  
  427. One thing that has occured to me is to just use two-d array:
  428.  
  429.   hextype map [NROWS][NCOLS];
  430.  
  431. And then have the routines take into account that every other row is
  432. indented. To see this, imagine a chess board where every other row is
  433. indented half a square.  Each square now touches 6 other squares and you have
  434. something similar to a hex map.  I think I would have serious problems
  435. getting this to work correctly, particularly line of sight.
  436.  
  437. Another idea: something kind of similar to a linked list:
  438.  
  439.   struct hextype {
  440.     int terrain, elevation;
  441.     hextype *NW, *NE, *E, *SE, *SW, *W;
  442.   };
  443.  
  444. This is a little more elegant, but how do you determine range?  If one hex
  445. could tell which of its surrounding hexes is closest to the target, you could
  446. have some sort of recursive function that traces the path between the two,
  447. thus revealing range and line of sight.  But, how do you determine which of
  448. the surrounding hexes is closest to the distant target?  What makes this
  449. method diffcult seems to be that the hexes are so isolated, only having
  450. contact with adjacent hexes.  And, they have no positioning information,
  451. other than relative to the surrounding hexes.
  452.  
  453. How about something that makes use of the numbers printed on each hex on an
  454. actual map sheet to determine some position information?
  455.  
  456. If I want to get really abstract, Robert Sedgewick's "Algorithms in C++" has
  457. a section on geometric algorithms, which deal with graphs (sets of vertices)
  458. and determine the shortest route between them, etc.  Even if I could get
  459. something like this to work, seems like it would be overkill for a simple hex
  460. map. 
  461.  
  462. Any suggestions out there?  This is my first post to CIS, so if I've done
  463. something uncool please let me know.
  464.  
  465. Dominic Vaughn  74720,1246  vcsc2059@sfsuvax1.sfsu.edu
  466. ...........................................................................
  467.  
  468. Fm: Bob Provencher/GD SL 71621,2632            # 309235 
  469. To: William D. Vaughn 74720,1246 (X)           Date: 06-Mar-93  13:51:52
  470.  
  471. Hi William, Welcome to GAMERS!  I've thought about this a little bit, and
  472. one idea I've come up with is a 2d array, with a 1/2 square shift on every
  473. other line.  On the even lines, add 1/2 to the array co-ordinate to find the
  474. "real" center of the hex, which can then be used for distance calculations.
  475.  
  476. I think this will also work for line of sight, if you've got two hexes, then
  477. step through all the hexes in the enclosing rectangle, shifting when
  478. appropriate, and decide how far from the line-of-sight each hex is, by
  479. taking the perpendicular to the line and the hex in question and computing
  480. the distance.  If it's within the .5 "squares" then it's in the line of
  481. sight.
  482.  
  483. Hope this helps.
  484. Bob
  485. ...........................................................................
  486.  
  487. Fm: William D. Vaughn 74720,1246               # 309447 
  488. To: Bob Provencher/GD SL 71621,2632 (X)        Date: 06-Mar-93  20:49:32
  489.  
  490. Thanks for the advice Bob.  I was leaning towards the 2-d array idea myself,
  491. but it seemed rather difficult because I was thinking of geometric objects
  492. instead of points.  It does seem pretty easy now: each hex's x and y
  493. coordinate are determined by their array index, with every even row adding
  494. 0.5 to one of the coordinates.  Range determined by feeding two points into
  495. the distance formula.  And LOS determined by distance between a hex's
  496. coordinates and the line connecting the the other two hexes.
  497.  
  498. Hopefully it will still seem that simple when I start writing code.  Thanks
  499. again for the help.
  500.  
  501. Dominic Vaughn
  502. ...........................................................................
  503.  
  504. Fm: yngvi 76703,3046                           # 309244 
  505. To: William D. Vaughn 74720,1246 (X)           Date: 06-Mar-93  14:06:06
  506.  
  507. Your first idea is a good one -- consider the hex map as a brick wall --
  508. alternating rows of overlapped squares or rectangles.  Your graphics can then
  509. display the map as hexagons.
  510.  
  511. LOS and other direction calculation in hex maps is actually pretty simple if
  512. you use 'slant matrix' calcs.  Unfortunately I dont have the calcs here.
  513. They're pretty basic, but I wouldnt want to guess.  The idea is that you
  514. transform the coordinates in a way that lets you number along diagonals
  515. rather than rows & columns.  once you do that the distance calcs are easier.
  516. LOS is more difficult since you have to check multiple directions, but not
  517. overwhelming.  There were a coupla articles on this in BYTE a long time ago
  518. (early 80's), and I'll try to dig them up. 
  519.  
  520. btw, the LOS calcs in my online sniper game are probably the most complicated
  521. part of the program -- running about 30 pages of code. One big problem is
  522. that calculations are not always reciprocal -- since you're dealing in
  523. discrete units (squares or hexes), diagonal lines are not always duplicated
  524. due to rounding.  So a tree may block when calculated in one direction but
  525. not in the other.  This leads to cases where one player has LOS and the other
  526. doesnt (not appreciated by the second player).  My eventual solution was to
  527. always do both calculations and allow the shot if either player has LOS. 
  528. this sometimes leads to odd looking shots, but it makes the game more fair.
  529. ...........................................................................
  530.  
  531. Fm: William D. Vaughn 74720,1246               # 309448 
  532. To: yngvi 76703,3046 (X)                       Date: 06-Mar-93  20:49:38
  533.  
  534. 30 pages of LOS code?  Ouch!  I get the feeling mine will be a lot shorter
  535. because my needs are simpler.  For one thing, with the way I have decided to
  536. go (2-d array) it will be very difficult to get LOS to exactly match what I
  537. get with a hex map.  I am trying to write something for BattleTech.  In that
  538. game, if the line connecting the centerpoints of two hexes crosses over even
  539. the tiniest portion of another hex, that hex is in the LOS.
  540.  
  541. With the method I am going to try (suggested by Bob), a hex is in the LOS if
  542. it's centerpoint is within 0.5 units (half a square) of the line connecting
  543. the other two hexes.  What you end up with is the equivalent of circular
  544. hexes, which is close enough for my needs (I don't need to get the exact same
  545. results as the board game).
  546.  
  547. Thanks for your advice.  That alternate geometry you mentioned sounded
  548. intertesting.  I guess that would be something oriented towards 60 degree
  549. angles instead of 90 degrees.
  550.  
  551. Dominic Vaughn
  552. ...........................................................................
  553.  
  554. Fm: yngvi 76703,3046                           # 309772 
  555. To: William D. Vaughn 74720,1246               Date: 07-Mar-93  12:56:27
  556.  
  557. One reason I couldnt use direct lines is speed -- calculating line connecting 2
  558. points requires too much cpu.  So I use a method that's similar to that for
  559. drawing diagonal lines of pixels -- moving one pixel/square at a time, and
  560. incrementing when needed.  That's where the discrepancy comes in -- eg, if
  561. the 2 pts are corners of a 13x3 box, you'd increment every 5:
  562.  
  563.         Xxxxx........
  564.              xxxxx
  565.                   xxY
  566.  
  567.   Starting from the other side, you'd see:
  568.         ........xxxxY
  569.            xxxxx
  570.         Xxx..
  571.  
  572.  So the same squares aren't always checked.  Another problem comes up with
  573. special cases like stone walls:
  574.  
  575.         ###X###############
  576.             .............Y
  577.  
  578. Here X is in a window (# = bldg walls).  If you use the normal algorithm for
  579. either of these guys, it would hit a wall at some point and they would be
  580. unable to sight.  So there need to be special routines to handle these sorts
  581. of situations.
  582. ...........................................................................
  583.  
  584. Fm: Dave Menconi 72350,602                     # 310815 
  585. To: William D. Vaughn 74720,1246 (X)           Date: 09-Mar-93  01:28:34
  586.  
  587. My approach to LOS and ranges would be to mimic the calculation you would do
  588. in a board game. I would develop an algorithm that would actual "walk" the
  589. grid from one point to another. For range you count the hexes; for LOS you
  590. look for blocking hexes. For range this would be slower than a mathematical
  591. solution. For LOS I can't see how you can avoid walking the hexes. Since you
  592. have to walk the hexes using a graph would be a pretty good solution (it
  593. seems counter-intuitive -- seems like some kind of array would be better).
  594. You can use a breadth-first search to find the shortest route(s) and then
  595. check to see if any of the hexes are blocked.
  596.  
  597. Remember that in most games there is some limit to how far you go -- the
  598. weapons have ranges and past those ranges it might as well be infinite. This
  599. means that you can trim the searches. Also, a bredth first search on a 6-way
  600. graph could be pretty costly but you can reduce it if you limit the search to
  601. look only in a particular direction.
  602.  
  603. Dave
  604. ...........................................................................
  605.  
  606. Fm: William D. Vaughn 74720,1246               # 311370 
  607. To: Dave Menconi 72350,602 (X)                 Date: 09-Mar-93  23:53:49
  608.  
  609. Dave,
  610.  
  611. I agree with you that having the program walk the hexes is the best way to
  612. determine range and LOS.  I had replied to someone else on this thread that I
  613. was going to try to do everything with simple math: use the distance formula
  614. to calculate range, to determine if a hex blocks LOS calculate it's distance
  615. from line, etc.  Once I started writing the code, I realized that it was just
  616. too unfaithful to the game mechanics of an actual hex map.
  617.  
  618. In my orignal post I mentioned the possibility of using using graphs and
  619. breadth-first searches.  I am now leaning against this.  For one thing, it
  620. just seems inefficient.  The graph routines are designed for random points
  621. and vertices, and I don't know if there is any way to let them take advantage
  622. of the regularity and structure of a hex map.  The other reason: I've looked
  623. at the code for graphs, and do have a dim understanding of them, but I don't
  624. know if I could write them.
  625.  
  626. My current plan is to use a 2-d array of hexes.  Each hex would contain,
  627. among other things, an X and Y coordinate.  To walk the map between hexes A
  628. and B, I would:
  629.  
  630. 1. Calculate angle between A and B (using their x and y coordinates)
  631.  
  632. 2. Determine which of the 6 hexes surrounding A is closest to that angle.
  633.    (for example, the angle to the NW hex is 120 degrees, so if the angle
  634.    between A and B is closer to 120 than to 60 or 180, the NW hex would
  635.    be chosen)
  636.  
  637. 3. Call that hex C.  If C=B, we are done.  Otherwise, go to step 1 using
  638.    C and B.
  639.  
  640. William
  641. ...........................................................................
  642.  
  643. Fm: yngvi 76703,3046                           # 311583 
  644. To: William D. Vaughn 74720,1246 (X)           Date: 10-Mar-93  13:43:29
  645.  
  646. There will still be times when you travers hex edge, rather than move thru
  647. the hex itself. Whenever you traverse a hexside the terrain on both sides is
  648. relevant.  The rules may vary -- it may be that blocking terrain in either
  649. hex will block LOS, or blocking terrain must be in both hexes to block.  So
  650. for every hexside, you will need to start a new thread to follow. 
  651.  
  652. In addition, your calculation of 'best' angle is still going to depend on
  653. which hex you use as your starting point.  Rounding will still be a factor --
  654. eg, the choice of hex used for A to B might not be the same as that for B to
  655. A. This is analogous to drawing a line pixel by pixel.  Since you're mapping
  656. a continuous line to a discrete coordinate system, the result will not be a
  657. smooth line. 
  658. ...........................................................................
  659.  
  660. Fm: Dave Menconi 72350,602                     # 310828 
  661. To: Bob Provencher/GD SL 71621,2632 (X)        Date: 09-Mar-93  02:36:42
  662.  
  663. Notwistanding what I said before, I don't think a graph is the way to go. I
  664. reached that conclusion by considering the best way to create a graph. First
  665. you put all the data into an array. Then you make each link a 2 byte index
  666. into the array. That way you save 12 of the 24 bytes. But you might as well
  667. make the array 2 dimentional and make the 2 byte indexes 2 1 byte indexes.
  668. Well, you quickly see that you can calculate the 6 indexes that I was going
  669. to store so you don't need to store them. There you are with your 2
  670. dimentional array... 
  671.  
  672. The way Chris Crawford calculated LOS and range in Tanktics (I didn't write
  673. it but I certainly saw the code) was to calculate a primary and secondary
  674. direction that the target hex has from the starting hex. Then he would look
  675. in each of the two hexes and consider which one had the "best" terrain for
  676. the particular purpose (usually you're trying to figure out more than the
  677. shortest distance -- cover and movement points were also considered). Then he
  678. would step in that direction, find a new primary and secondary hex and do it
  679. again.  
  680.  
  681. If you just want the shortest (in number of hexes) distance you can always
  682. use the "primary" direction and just keep stepping in that direction. You can
  683. get "fewest movement points" using the primary/secondary technique. Note that
  684. a breadth first search will give you a better answer than the primary /
  685. secondary method in some cases but not THAT much better.
  686.  
  687. I'm sorry but I can't remember what the algorithm for figuring out the
  688. primary and secondary hexes are...
  689. ...........................................................................
  690.  
  691. Fm: Bob Provencher/GD SL 71621,2632            # 311107 
  692. To: Dave Menconi 72350,602 (X)                 Date: 09-Mar-93  16:50:43
  693.  
  694. Hi Dave -
  695.  
  696. I can't think of any benefits to the graph method.  One idea I had was the
  697. ability to find the shortest non-obstructed path between two hexes, using
  698. matrix representations of each hex, and something called Warshalls
  699. algorithm.  The problem is that the algorithm is O(n^3)!
  700.  
  701. For line of sight I can't see how the graph would work either.
  702.  
  703. I guess I need to understand the algorithm your talking about.  It sounds
  704. like it is the same for both the LOS and shortest path calculation, which to
  705. me are very different.
  706.  
  707. Bob
  708. ...........................................................................
  709.  
  710. Fm: Dave Menconi 72350,602                     # 311399 
  711. To: Bob Provencher/GD SL 71621,2632 (X)        Date: 10-Mar-93  01:07:58
  712.  
  713. Bob,
  714.  
  715. As I say, it is possible to calculate the range without stepping in each hex;
  716. you can do it mathematically. I don't know the algorithm off hand but I know
  717. that others have found it so it must exist (they think therefor it is? -- no
  718. never mind <G>).
  719.  
  720. On the other hand, you must step in each hex to get the LOS -- it can't be
  721. done mathematically. So you have to write a "walk the line" routine. Since
  722. you have write one anyway, and since it WILL give you the range (if you write
  723. it so that it will) why not use it to give you the range? It won't be as
  724. efficient but it will be plenty fast enough (it was plenty fast enough on an
  725. Atari 800 and on a Kim -- it will be fast enough on a PC or a Mac!).
  726.  
  727. The algorithm is so simple it's almost stupid. It's O(n) where n is the
  728. range. The only thing you need (that I don't know how to do) is a routine
  729. that will tell you which of the 6 directions to go in to get from one hex to
  730. another. I think you compare the x and y (actually the delta x and delta y)
  731. but I'm not sure what the exact algorithm is.
  732.  
  733. Dave
  734. ...........................................................................
  735.  
  736. Fm: yngvi 76703,3046                           # 311584 
  737. To: Dave Menconi 72350,602 (X)                 Date: 10-Mar-93  13:43:34
  738.  
  739. Right, the slant matrix algorithm will give distances by simple addition and
  740. subtraction, so is quite fast.
  741.  
  742.   Calculating the range is handy to do first, since you can eliminate LOS
  743. calcs for anything out of range.  You can also find the closest (or
  744. strongest, whatever) target in range first, and then do detailed LOS calcs.
  745.  
  746.  Steve
  747. ...........................................................................
  748.  
  749. Fm: Bob Provencher/GD SL 71621,2632            # 311666 
  750. To: Dave Menconi 72350,602 (X)                 Date: 10-Mar-93  17:40:36
  751.  
  752. Hi Dave -
  753.  
  754. I'm curious, have you implemented the LOS by walking stepping hexes?  I'd
  755. like to see it because I'm really confused as to how to do it that way.  Or
  756. do you mean you "walk the line" and step through the intersecting hexes?
  757. (That's the way I suggested it be done at the beginning of the thread)
  758.  
  759. Bob
  760. ...........................................................................
  761.  
  762. Fm: Dave Menconi 72350,602                     # 311974 
  763. To: yngvi 76703,3046                           Date: 11-Mar-93  01:10:19
  764.  
  765. Steve,
  766.  
  767. It may solve the first problem (hex edge traversal) to have the routine
  768. return 2 hexes -- a primary and a secondary. Perhaps it could also return a
  769. value that indicates how secondary the secondary hex is (i.e. how close to
  770. the hex edge is the line). In cases where the secondary hex is considered
  771. important, one could add a rule that the LOS is blocked only if the primary
  772. and secondary hexes are BOTH blocked.
  773.  
  774. I would not actually move into the secondary hex and check line of sight
  775. recursively from there because that seems to be a) very expensive in time and
  776. space and b) of marginal value (i.e. only rarely would you get different
  777. results).
  778.  
  779. Waddaya think? Would this shortcut yield reasonable results?
  780.  
  781. Now, about your second point (AB isn't the same as BA). Perhaps you could
  782. always draw the line in the same direction. For example, you might always
  783. pick the hex that's farthest up and to the right to start from. That means
  784. that AB still isn't the same as BA but we always calculate AB, never BA so we
  785. always get the same answer. Cheap and dirty but workable, right?
  786.  
  787. Dave
  788. ...........................................................................
  789.  
  790. Fm: Dave Menconi 72350,602                     # 311973 
  791. To: William D. Vaughn 74720,1246 (X)           Date: 11-Mar-93  01:10:11
  792.  
  793. William,
  794.  
  795. I'm wondering how you will calculate that angle. Will the standard angle
  796. calculation (arctangent of dy/dx) work in a hex grid!? Also, since you only
  797. need 6 possible angles, it should be possible to simplify the algorithm.
  798.  
  799. Dave
  800. ...........................................................................
  801.  
  802. Fm: William D. Vaughn 74720,1246               # 312481 
  803. To: Dave Menconi 72350,602 (X)                 Date: 12-Mar-93  01:05:32
  804.  
  805. Dave, yes I used atan (dy/dx), though there were a couple of minor hassles.
  806. For one thing, I had to make adjustments to this if the point did not lie in
  807. quadrant I (eg., for dy and dx both negative I used atan(dy/dx)+PI). Also
  808. dx=0 required special treatment.  I converted the result to degrees. 
  809.  
  810. As for where I got the coordinates: I used the hex's array index.  For
  811. example, the first hex in each row has x=0, the fourth has x=3, etc.  The y
  812. coordinate was a little trickier.  If the distance between hex centers is 1.0
  813. horizontally, it is sqrt(.75) vertically.  I made this a constant (const
  814. double VERTFACT=sqrt(0.75) ) and set each hex's y coordinate to rowNum *
  815. VERTFACT. Also, every odd numbered row is indented by 0.5, or x=x+0.5. Taking
  816. all into account, hex [11][3] has coordinates (11.5, 2.598). 
  817.  
  818. This is about as far as I've gotten.  The next step will be to determine
  819. which of the six directions is closest to the angle between two hexes, which
  820. will simply require rounding the angle to the nearest 60 degrees.  Then it
  821. shouldn't too hard to walk the range! (I hope anyway).
  822.  
  823. William
  824. ...........................................................................
  825.  
  826. Fm: Dave Menconi 72350,602                     # 311971 
  827. To: Bob Provencher/GD SL 71621,2632 (X)        Date: 11-Mar-93  01:10:02
  828.  
  829. Bob,
  830.  
  831. I'm talking about "walking the line." I'm sorry, I must have missed your
  832. description.
  833.  
  834. I think I confused you by talking about the Tanktics movement algorithm. It
  835. would not just travel the straight line between two points but actually try
  836. to find "the best path" according to a set of rules. It was kind of cute
  837. because it would travel through clear terrain at the beginning of the turn
  838. and then "duck into" good cover at the end of the turn so that units were
  839. always in cover when the other player got to shoot. <G>
  840.  
  841. Dave
  842. ...........................................................................
  843.  
  844. Fm: Bob Provencher/GD SL 71621,2632            # 312225 
  845. To: Dave Menconi 72350,602 (X)                 Date: 11-Mar-93  16:47:24
  846.  
  847. Hi Dave -
  848.  
  849. Oh ok, I see!  Yeah, ducking into cover is a healthy thing for a unit to do
  850. before the opponents turn <g>.
  851.  
  852. Bob
  853. ...........................................................................
  854.  
  855.  
  856.