tilemath.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include "G3d_intern.h"
  6. /*---------------------------------------------------------------------------*/
  7. /*!
  8. * \brief
  9. *
  10. * Converts index <em>tileIndex</em> into tile-coordinates
  11. * <em>(xTile, yTile, zTile)</em>.
  12. *
  13. * \param map
  14. * \param tileIndex
  15. * \param xTile
  16. * \param yTile
  17. * \param zTile
  18. * \return void
  19. */
  20. void
  21. G3d_tileIndex2tile(G3D_Map * map, int tileIndex, int *xTile, int *yTile,
  22. int *zTile)
  23. {
  24. int tileIndex2d;
  25. *zTile = tileIndex / map->nxy;
  26. tileIndex2d = tileIndex % map->nxy;
  27. *yTile = tileIndex2d / map->nx;
  28. *xTile = tileIndex2d % map->nx;
  29. }
  30. /*---------------------------------------------------------------------------*/
  31. /*!
  32. * \brief
  33. *
  34. * Returns tile-index corresponding to tile-coordinates <em>(xTile,
  35. * yTile, zTile)</em>.
  36. *
  37. * \param map
  38. * \param xTile
  39. * \param yTile
  40. * \param zTile
  41. * \return int
  42. */
  43. int G3d_tile2tileIndex(G3D_Map * map, int xTile, int yTile, int zTile)
  44. {
  45. return map->nxy * zTile + map->nx * yTile + xTile;
  46. }
  47. /*---------------------------------------------------------------------------*/
  48. /*!
  49. * \brief
  50. *
  51. * Computes the cell-coordinates <em>(x, y, z)</em>
  52. * which correspond to the origin of the tile with tile-coordinates <em>(xTile,
  53. * yTile, zTile)</em>.
  54. *
  55. * \param map
  56. * \param xTile
  57. * \param yTile
  58. * \param zTile
  59. * \param x
  60. * \param y
  61. * \param z
  62. * \return void
  63. */
  64. void
  65. G3d_tileCoordOrigin(G3D_Map * map, int xTile, int yTile, int zTile, int *x,
  66. int *y, int *z)
  67. {
  68. *x = map->tileX * xTile;
  69. *y = map->tileY * yTile;
  70. *z = map->tileZ * zTile;
  71. }
  72. /*---------------------------------------------------------------------------*/
  73. /*!
  74. * \brief
  75. *
  76. * Computes the cell-coordinates <em>(x, y, z)</em> which correspond to
  77. * the origin of the tile with <em>tileIndex</em>.
  78. *
  79. * \param map
  80. * \param tileIndex
  81. * \param x
  82. * \param y
  83. * \param z
  84. * \return void
  85. */
  86. void G3d_tileIndexOrigin(G3D_Map * map, int tileIndex, int *x, int *y, int *z)
  87. {
  88. int xTile, yTile, zTile;
  89. G3d_tileIndex2tile(map, tileIndex, &xTile, &yTile, &zTile);
  90. G3d_tileCoordOrigin(map, xTile, yTile, zTile, x, y, z);
  91. }
  92. /*---------------------------------------------------------------------------*/
  93. /*!
  94. * \brief
  95. *
  96. * Converts
  97. * cell-coordinates <em>(x, y, z)</em> into tile-coordinates <em>(xTile, yTile,
  98. * zTile)</em> and the coordinate of the cell <em>(xOffs, yOffs, zOffs)</em> within
  99. * the tile.
  100. *
  101. * \param map
  102. * \param x
  103. * \param y
  104. * \param z
  105. * \param xTile
  106. * \param yTile
  107. * \param zTile
  108. * \param xOffs
  109. * \param yOffs
  110. * \param zOffs
  111. * \return void
  112. */
  113. void
  114. G3d_coord2tileCoord(G3D_Map * map, int x, int y, int z, int *xTile,
  115. int *yTile, int *zTile, int *xOffs, int *yOffs,
  116. int *zOffs)
  117. {
  118. *xTile = x / map->tileX;
  119. *xOffs = x % map->tileX;
  120. *yTile = y / map->tileY;
  121. *yOffs = y % map->tileY;
  122. *zTile = z / map->tileZ;
  123. *zOffs = z % map->tileZ;
  124. }
  125. /*---------------------------------------------------------------------------*/
  126. /*!
  127. * \brief
  128. *
  129. * Converts cell-coordinates <em>(x, y, z)</em> into
  130. * <em>tileIndex</em> and the <em>offset</em> of the cell within the tile.
  131. *
  132. * \param map
  133. * \param x
  134. * \param y
  135. * \param z
  136. * \param tileIndex
  137. * \param offset
  138. * \return void
  139. */
  140. void
  141. G3d_coord2tileIndex(G3D_Map * map, int x, int y, int z, int *tileIndex,
  142. int *offset)
  143. {
  144. int xTile, yTile, zTile, xOffs, yOffs, zOffs;
  145. G3d_coord2tileCoord(map, x, y, z,
  146. &xTile, &yTile, &zTile, &xOffs, &yOffs, &zOffs);
  147. *tileIndex = G3d_tile2tileIndex(map, xTile, yTile, zTile);
  148. *offset = zOffs * map->tileXY + yOffs * map->tileX + xOffs;
  149. }
  150. /*---------------------------------------------------------------------------*/
  151. /*!
  152. * \brief
  153. *
  154. * Returns 1 if
  155. * cell-coordinate <em>(x, y, z)</em> is a coordinate inside the region. Returns 0
  156. * otherwise.
  157. *
  158. * \param map
  159. * \param x
  160. * \param y
  161. * \param z
  162. * \return int
  163. */
  164. int G3d_coordInRange(G3D_Map * map, int x, int y, int z)
  165. {
  166. return (x >= 0) && (x < map->region.cols) && (y >= 0) &&
  167. (y < map->region.rows) && (z >= 0) && (z < map->region.depths);
  168. }
  169. /*---------------------------------------------------------------------------*/
  170. /*!
  171. * \brief
  172. *
  173. * Returns 1 if <em>tileIndex</em> is a valid index for <em>map</em>.
  174. * Returns 0 otherwise.
  175. *
  176. * \param map
  177. * \param tileIndex
  178. * \return int
  179. */
  180. int G3d_tileIndexInRange(G3D_Map * map, int tileIndex)
  181. {
  182. return (tileIndex < map->nTiles) && (tileIndex >= 0);
  183. }
  184. /*---------------------------------------------------------------------------*/
  185. /*!
  186. * \brief
  187. *
  188. * Returns 1 if
  189. * tile-coordinate <em>(x, y, z)</em> is a coordinate inside tile cube. Returns 0
  190. * otherwise.
  191. *
  192. * \param map
  193. * \param x
  194. * \param y
  195. * \param z
  196. * \return int
  197. */
  198. int G3d_tileInRange(G3D_Map * map, int x, int y, int z)
  199. {
  200. return (x >= 0) && (x < map->nx) && (y >= 0) && (y < map->ny) &&
  201. (z >= 0) && (z < map->nz);
  202. }
  203. /*---------------------------------------------------------------------------*/
  204. /*!
  205. * \brief
  206. *
  207. * Computes the dimensions of the tile when clipped to fit the
  208. * region of <em>map</em>. The clipped dimensions are returned in <em>rows</em>,
  209. * <em>cols</em>, <em>depths</em>. The complement is returned in <em>xRedundant</em>,
  210. * <em>yRedundant</em>, and <em>zRedundant</em>. This function returns the number of
  211. * cells in the clipped tile.
  212. *
  213. * \param map
  214. * \param tileIndex
  215. * \param rows
  216. * \param cols
  217. * \param depths
  218. * \param xRedundant
  219. * \param yRedundant
  220. * \param zRedundant
  221. * \return int
  222. */
  223. int
  224. G3d_computeClippedTileDimensions(G3D_Map * map, int tileIndex, int *rows,
  225. int *cols, int *depths, int *xRedundant,
  226. int *yRedundant, int *zRedundant)
  227. {
  228. int x, y, z;
  229. G3d_tileIndex2tile(map, tileIndex, &x, &y, &z);
  230. if ((x != map->clipX) && (y != map->clipY) && (z != map->clipZ)) {
  231. return map->tileSize;
  232. }
  233. if (x != map->clipX) {
  234. *cols = map->tileX;
  235. *xRedundant = 0;
  236. }
  237. else {
  238. *cols = (map->region.cols - 1) % map->tileX + 1;
  239. *xRedundant = map->tileX - *cols;
  240. }
  241. if (y != map->clipY) {
  242. *rows = map->tileY;
  243. *yRedundant = 0;
  244. }
  245. else {
  246. *rows = (map->region.rows - 1) % map->tileY + 1;
  247. *yRedundant = map->tileY - *rows;
  248. }
  249. if (z != map->clipZ) {
  250. *depths = map->tileZ;
  251. *zRedundant = 0;
  252. }
  253. else {
  254. *depths = (map->region.depths - 1) % map->tileZ + 1;
  255. *zRedundant = map->tileZ - *depths;
  256. }
  257. /* printf ("%d (%d %d %d): (%d %d) (%d %d) (%d %d), %d\n", */
  258. /* tileIndex, x, y, z, *rows, *xRedundant, *cols, *yRedundant, */
  259. /* *depths, *zRedundant, *depths * *cols * *rows); */
  260. return *depths * *cols * *rows;
  261. }
  262. /*---------------------------------------------------------------------------*/
  263. /*!
  264. * \brief
  265. *
  266. * Returns 1 if region-coordinates <em>(north, west, bottom)</em> are
  267. * inside the region of <em>map</em>. Returns 0 otherwise.
  268. *
  269. * \param map
  270. * \param north
  271. * \param west
  272. * \param bottom
  273. * \return int
  274. */
  275. int G3d_isValidLocation(G3D_Map * map, double north, double east, double top)
  276. {
  277. return ((north >= map->region.south) && (north <= map->region.north) &&
  278. (east >= map->region.west) && (east <= map->region.east) &&
  279. (((top >= map->region.bottom) && (top <= map->region.top)) ||
  280. ((top <= map->region.bottom) && (top >= map->region.top))));
  281. }
  282. /*---------------------------------------------------------------------------*/
  283. /*!
  284. * \brief
  285. *
  286. * Converts region-coordinates <em>(north, west,
  287. * bottom)</em> into cell-coordinates <em>(x, y, z)</em>.
  288. *
  289. * \param map
  290. * \param north
  291. * \param west
  292. * \param bottom
  293. * \param x
  294. * \param y
  295. * \param z
  296. * \return void
  297. */
  298. void
  299. G3d_location2coord(G3D_Map * map, double north, double east, double top,
  300. int *x, int *y, int *z)
  301. {
  302. if (!G3d_isValidLocation(map, north, east, top))
  303. G3d_fatalError("location2coord: location not in region");
  304. *y = (north - map->region.south) / (map->region.north -
  305. map->region.south) *
  306. (map->region.rows - 1);
  307. *x = (east - map->region.west) / (map->region.east -
  308. map->region.west) * (map->region.cols -
  309. 1);
  310. *z = (top - map->region.bottom) / (map->region.top -
  311. map->region.bottom) *
  312. (map->region.depths - 1);
  313. }