GXS.GeometryCoordinates.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. //
  2. // The graphics engine GXScene https://github.com/glscene
  3. //
  4. unit GXS.GeometryCoordinates;
  5. (*
  6. Helper functions to convert between different three dimensional coordinate
  7. systems. Room for optimisations.
  8. *)
  9. interface
  10. uses
  11. System.Math,
  12. GLScene.VectorGeometry;
  13. (* Convert Cylindrical to Cartesian with no checks. Single version with theta in rad
  14. Ref: http://mathworld.wolfram.com/CylindricalCoordinates.html *)
  15. procedure Cylindrical_Cartesian(const r, theta, z1: single; var x, y, z: single); overload;
  16. (* Convert Cylindrical to Cartesian with no checks. Double version with theta in rads
  17. Ref: http://mathworld.wolfram.com/CylindricalCoordinates.html *)
  18. procedure Cylindrical_Cartesian(const r, theta, z1: double; var x, y, z: double); overload;
  19. (* Convert Cylindrical to Cartesian with checks. Single version with theta in rad
  20. ierr: [0] = ok,
  21. [1] = r out of bounds. Acceptable r: [0,inf)
  22. [2] = theta out of bounds. Acceptable theta: [0,2pi)
  23. [3] = z1 out of bounds. Acceptable z1 : (-inf,inf)
  24. Ref: http://mathworld.wolfram.com/CylindricalCoordinates.html *)
  25. procedure Cylindrical_Cartesian(const r, theta, z1: single; var x, y, z: single;
  26. var ierr: integer); overload;
  27. (* Convert Cylindrical to Cartesian with checks. Double version with theta in rad
  28. ierr: [0] = ok,
  29. [1] = r out of bounds. Acceptable r: [0,inf)
  30. [2] = theta out of bounds. Acceptable theta: [0,2pi)
  31. [3] = z1 out of bounds. Acceptable z1 : (-inf,inf)
  32. Ref: http://mathworld.wolfram.com/CylindricalCoordinates.html *)
  33. procedure Cylindrical_Cartesian(const r, theta, z1: double; var x, y, z: double;
  34. var ierr: integer); overload;
  35. (* Convert Cartesian to Cylindrical no checks. Single *)
  36. procedure Cartesian_Cylindrical(const x, y, z1: single; var r, theta, z: single); overload;
  37. (* Convert Cartesian to Cylindrical no checks. Duoble *)
  38. procedure Cartesian_Cylindrical(const x, y, z1: double; var r, theta, z: double); overload;
  39. (* Convert Spherical to Cartesian with no checks. [single] theta,phi in rads
  40. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html *)
  41. procedure Spherical_Cartesian(const r, theta, phi: single; var x, y, z: single); overload;
  42. (* Convert Spherical to Cartesian with no checks. Double version theta,phi in rads.
  43. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html *)
  44. procedure Spherical_Cartesian(const r, theta, phi: double; var x, y, z: double); overload;
  45. (* Convert Spherical to Cartesian with checks. theta,phi in rad
  46. ierr: [0] = ok,
  47. [1] = r out of bounds
  48. [2] = theta out of bounds
  49. [3] = phi out of bounds
  50. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html *)
  51. procedure Spherical_Cartesian(const r, theta, phi: single; var x, y, z: single;
  52. var ierr: integer); overload;
  53. (* Convert Spherical to Cartesian with checks. theta,phi in rad
  54. ierr: [0] = ok,
  55. [1] = r out of bounds
  56. [2] = theta out of bounds
  57. [3] = phi out of bounds
  58. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html *)
  59. procedure Spherical_Cartesian(const r, theta, phi: double; var x, y, z: double;
  60. var ierr: integer); overload;
  61. (* convert Cartesian to Spherical, no checks, single
  62. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html
  63. NB: Could be optimised by using jclmath.pas unit? *)
  64. procedure Cartesian_Spherical(const x, y, z: single; var r, theta, phi: single); overload;
  65. procedure Cartesian_Spherical(const v: TAffineVector; var r, theta, phi: single); overload;
  66. // Convert cartesion to spherical [double]
  67. (* convert Cartesian to Spherical, no checks, double
  68. Ref: http://mathworld.wolfram.com/SphericalCoordinates.html
  69. NB: Could be optimised by using jclmath.pas unit? *)
  70. procedure Cartesian_Spherical(const x, y, z: double; var r, theta, phi: double); overload;
  71. (* Convert Prolate-Spheroidal to Cartesian with no checks. [single] eta, phi in rad
  72. A system of curvilinear coordinates in which two sets of coordinate surfaces are
  73. obtained by revolving the curves of the elliptic cylindrical coordinates about
  74. the x-axis, which is relabeled the z-axis. The third set of coordinates
  75. consists of planes passing through this axis.
  76. The coordinate system is parameterised by parameter a. A default value of a=1 is
  77. suggesed:
  78. http://documents.wolfram.com/v4/AddOns/StandardPackages/Calculus/VectorAnalysis.html
  79. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  80. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: single;
  81. var x, y, z: single); overload;
  82. (* Convert Prolate-Spheroidal to Cartesian with no checks. Double version. eta,phi in rad
  83. A system of curvilinear coordinates in which two sets of coordinate surfaces are
  84. obtained by revolving the curves of the elliptic cylindrical coordinates about
  85. the x-axis, which is relabeled the z-axis. The third set of coordinates
  86. consists of planes passing through this axis.
  87. The coordinate system is parameterised by parameter a. A default value of a=1 is
  88. suggesed:
  89. http://documents.wolfram.com/v4/AddOns/StandardPackages/Calculus/VectorAnalysis.html
  90. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  91. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: double;
  92. var x, y, z: double); overload;
  93. (* Convert Prolate-Spheroidal to Cartesian with checks. [single] eta,phi in rad
  94. ierr: [0] = ok,
  95. [1] = xi out of bounds. Acceptable xi: [0,inf)
  96. [2] = eta out of bounds. Acceptable eta: [0,pi]
  97. [3] = phi out of bounds. Acceptable phi: [0,2pi)
  98. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  99. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: single;
  100. var x, y, z: single; var ierr: integer); overload;
  101. (* Convert Prolate-Spheroidal to Cartesian with checks. Double Version. eta,phi in rad
  102. ierr: [0] = ok,
  103. [1] = xi out of bounds. Acceptable xi: [0,inf)
  104. [2] = eta out of bounds. Acceptable eta: [0,pi]
  105. [3] = phi out of bounds. Acceptable phi: [0,2pi)
  106. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  107. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: double;
  108. var x, y, z: double; var ierr: integer); overload;
  109. (* Convert Oblate-Spheroidal to Cartesian with no checks. [Single] eta, phi in rad
  110. A system of curvilinear coordinates in which two sets of coordinate surfaces are
  111. obtained by revolving the curves of the elliptic cylindrical coordinates about
  112. the y-axis which is relabeled the z-axis. The third set of coordinates consists
  113. of planes passing through this axis.
  114. The coordinate system is parameterised by parameter a. A default value of a=1 is
  115. suggesed:
  116. http://documents.wolfram.com/v4/AddOns/StandardPackages/Calculus/VectorAnalysis.html
  117. Ref: http://mathworld.wolfram.com/OblateSpheroidalCoordinates.html *)
  118. procedure OblateSpheroidal_Cartesian(const xi, eta, phi, a: single;
  119. var x, y, z: single); overload;
  120. (* Convert Oblate-Spheroidal to Cartesian with no checks. Double Version eta, phi in rad.
  121. A system of curvilinear coordinates in which two sets of coordinate surfaces are
  122. obtained by revolving the curves of the elliptic cylindrical coordinates about
  123. the y-axis which is relabeled the z-axis. The third set of coordinates consists
  124. of planes passing through this axis.
  125. The coordinate system is parameterised by parameter a. A default value of a=1 is
  126. suggesed:
  127. http://documents.wolfram.com/v4/AddOns/StandardPackages/Calculus/VectorAnalysis.html
  128. Ref: http://mathworld.wolfram.com/OblateSpheroidalCoordinates.html *)
  129. procedure OblateSpheroidal_Cartesian(const xi, eta, phi, a: double;
  130. var x, y, z: double); overload;
  131. (* Convert Oblate-Spheroidal to Cartesian with checks. eta,phi in rad
  132. ierr: [0] = ok,
  133. [1] = xi out of bounds. Acceptable xi: [0,inf)
  134. [2] = eta out of bounds. Acceptable eta: [-0.5*pi,0.5*pi]
  135. [3] = phi out of bounds. Acceptable phi: [0,2*pi)
  136. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  137. procedure OblateSpheroidal_Cartesian(const xi, eta, phi, a: single;
  138. var x, y, z: single; var ierr: integer); overload;
  139. (* Convert Oblate-Spheroidal to Cartesian with checks. Double Version eta,phi in rad.
  140. ierr: [0] = ok,
  141. [1] = xi out of bounds. Acceptable xi: [0,inf)
  142. [2] = eta out of bounds. Acceptable eta: [-0.5*pi,0.5*pi]
  143. [3] = phi out of bounds. Acceptable phi: [0,2*pi)
  144. Ref: http://mathworld.wolfram.com/ProlateSpheroidalCoordinates.html *)
  145. procedure OblateSpheroidal_Cartesian(const xi, eta, phi, a: double;
  146. var x, y, z: double; var ierr: integer); overload;
  147. (* Convert BiPolarCylindrical to Cartesian with no checks. u in rad
  148. http://mathworld.wolfram.com/BipolarCylindricalCoordinates.html *)
  149. procedure BipolarCylindrical_Cartesian(const u, v, z1, a: single;
  150. var x, y, z: single); overload;
  151. (* Convert BiPolarCylindrical to Cartesian with no checks. Double Version u in rad
  152. http://mathworld.wolfram.com/BipolarCylindricalCoordinates.html *)
  153. procedure BipolarCylindrical_Cartesian(const u, v, z1, a: double;
  154. var x, y, z: double); overload;
  155. (* Convert Oblate-Spheroidal to Cartesian with checks. u in rad
  156. ierr: [0] = ok,
  157. [1] = u out of bounds. Acceptable u: [0,2*pi)
  158. [2] = v out of bounds. Acceptable v: (-inf,inf)
  159. [3] = z1 out of bounds. Acceptable z1: (-inf,inf)
  160. Ref: http://mathworld.wolfram.com/BiPolarCylindricalCoordinates.html *)
  161. procedure BipolarCylindrical_Cartesian(const u, v, z1, a: single;
  162. var x, y, z: single; var ierr: integer); overload;
  163. (* Convert Oblate-Spheroidal to Cartesian with checks. Double Version u in rad
  164. ierr: [0] = ok,
  165. [1] = u out of bounds. Acceptable u: [0,2*pi)
  166. [2] = v out of bounds. Acceptable v: (-inf,inf)
  167. [3] = z1 out of bounds. Acceptable z1: (-inf,inf)
  168. Ref: http://mathworld.wolfram.com/BiPolarCylindricalCoordinates.html *)
  169. procedure BipolarCylindrical_Cartesian(const u, v, z1, a: double;
  170. var x, y, z: double; var ierr: integer); overload;
  171. // --------------------------------------------------------------------------
  172. implementation
  173. // --------------------------------------------------------------------------
  174. // ----- Cylindrical_Cartesian ---------------------------------------------
  175. procedure Cylindrical_Cartesian(const r, theta, z1: single; var x, y, z: single);
  176. begin
  177. SinCosine(theta, r, y, x);
  178. z := z1;
  179. end;
  180. // ----- Cylindrical_Cartesian -------------------------------------------------
  181. procedure Cylindrical_Cartesian(const r, theta, z1: double; var x, y, z: double);
  182. begin
  183. SinCosine(theta, r, y, x);
  184. z := z1;
  185. end;
  186. // ----- Cylindrical_Cartesian -------------------------------------------------
  187. procedure Cylindrical_Cartesian(const r, theta, z1: single; var x, y, z: single;
  188. var ierr: integer);
  189. begin
  190. { ** check input parameters }
  191. if (r < 0.0) then
  192. ierr := 1
  193. else if ((theta < 0.0) or (theta >= 2 * pi)) then
  194. ierr := 2
  195. else
  196. ierr := 0;
  197. if (ierr = 0) then
  198. begin
  199. SinCosine(theta, r, y, x);
  200. z := z1;
  201. end;
  202. end;
  203. // ----- Cylindrical_Cartesian -------------------------------------------------
  204. procedure Cylindrical_Cartesian(const r, theta, z1: double; var x, y, z: double;
  205. var ierr: integer);
  206. begin
  207. // check input parameters
  208. if (r < 0.0) then
  209. ierr := 1
  210. else if ((theta < 0.0) or (theta >= 2 * pi)) then
  211. ierr := 2
  212. else
  213. ierr := 0;
  214. if (ierr = 0) then
  215. begin
  216. SinCosine(theta, r, y, x);
  217. z := z1;
  218. end;
  219. end;
  220. // ----- Cartesian_Cylindrical -------------------------------------------------
  221. procedure Cartesian_Cylindrical(const x, y, z1: single; var r, theta, z: single);
  222. begin
  223. r := sqrt(x * x + y * y);
  224. theta := ArcTan2(y, x);
  225. z := z1;
  226. end;
  227. // ----- Cartesian_Cylindrical -------------------------------------------------
  228. procedure Cartesian_Cylindrical(const x, y, z1: double; var r, theta, z: double);
  229. begin
  230. r := sqrt(x * x + y * y);
  231. theta := ArcTan2(y, x);
  232. z := z1;
  233. end;
  234. // ----- Spherical_Cartesian ---------------------------------------------------
  235. procedure Spherical_Cartesian(const r, theta, phi: single; var x, y, z: single);
  236. var
  237. a: single;
  238. begin
  239. SinCosine(phi, r, a, z); // z = r*cos(phi), a=r*sin(phi)
  240. SinCosine(theta, a, y, x); // x = a*cos(theta), y = a*sin(theta)}
  241. end;
  242. // ----- Spherical_Cartesian ---------------------------------------------------
  243. procedure Spherical_Cartesian(const r, theta, phi: double; var x, y, z: double);
  244. var
  245. a: double;
  246. begin
  247. SinCosine(phi, r, a, z); // z = r*cos(phi), a=r*sin(phi)
  248. SinCosine(theta, a, y, x); // x = a*cos(theta), y = a*sin(theta)}
  249. end;
  250. // ----- Spherical_Cartesian ---------------------------------------------------
  251. procedure Spherical_Cartesian(const r, theta, phi: single; var x, y, z: single;
  252. var ierr: integer);
  253. var
  254. a: single;
  255. begin
  256. if (r < 0.0) then
  257. ierr := 1
  258. else if ((theta < 0.0) or (theta >= 2 * pi)) then
  259. ierr := 2
  260. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  261. ierr := 3
  262. else
  263. ierr := 0;
  264. if (ierr = 0) then
  265. begin
  266. SinCosine(phi, r, a, z); // z = r*cos(phi), a=r*sin(phi)
  267. SinCosine(theta, a, y, x); // x = a*cos(theta), y = a*sin(theta)}
  268. end;
  269. end;
  270. // ----- Spherical_Cartesian ---------------------------------------------------
  271. procedure Spherical_Cartesian(const r, theta, phi: double; var x, y, z: double;
  272. var ierr: integer);
  273. var
  274. a: double;
  275. begin
  276. if (r < 0.0) then
  277. ierr := 1
  278. else if ((theta < 0.0) or (theta >= 2 * pi)) then
  279. ierr := 2
  280. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  281. ierr := 3
  282. else
  283. ierr := 0;
  284. if (ierr = 0) then
  285. begin
  286. SinCosine(phi, r, a, z); // z = r*cos(phi), a=r*sin(phi)
  287. SinCosine(theta, a, y, x); // x = a*cos(theta), y = a*sin(theta)}
  288. end;
  289. end;
  290. // ----- Cartesian_Spherical ---------------------------------------------------
  291. procedure Cartesian_Spherical(const x, y, z: single; var r, theta, phi: single);
  292. begin
  293. r := sqrt((x * x) + (y * y) + (z * z));
  294. theta := ArcTan2(y, x);
  295. phi := ArcCosine(z / r);
  296. end;
  297. procedure Cartesian_Spherical(const v: TAffineVector; var r, theta, phi: single);
  298. begin
  299. r := VectorLength(v);
  300. theta := ArcTan2(v.y, v.x);
  301. phi := ArcCosine(v.z / r);
  302. end;
  303. // ----- Cartesian_Spherical ---------------------------------------------------
  304. procedure Cartesian_Spherical(const x, y, z: double; var r, theta, phi: double);
  305. begin
  306. r := sqrt((x * x) + (y * y) + (z * z));
  307. theta := ArcTan2(y, x);
  308. phi := ArcCosine(z / r);
  309. end;
  310. // ----- ProlateSpheroidal_Cartesian -------------------------------------------
  311. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: single; var x, y, z: single);
  312. var
  313. sn, cs, snphi, csphi, shx, chx: single;
  314. begin
  315. SinCosine(eta, a, sn, cs);
  316. SinCosine(phi, snphi, csphi);
  317. shx := sinh(xi);
  318. chx := cosh(xi);
  319. x := sn * shx * csphi; // x = a*sin(eta)*sinh(xi)*cos(phi)
  320. y := sn * shx * snphi; // y = a*sin(eta)*sinh(xi)*sin(phi)
  321. z := cs * chx; // z = a*cos(eta)*cosh(xi)
  322. end;
  323. // ----- ProlateSpheroidal_Cartesian -------------------------------------------
  324. procedure ProlateSpheroidal_Cartesian(const xi, eta, phi, a: double; var x, y, z: double);
  325. var
  326. sn, cs, snphi, csphi, shx, chx: double;
  327. begin
  328. SinCosine(eta, a, sn, cs);
  329. SinCosine(phi, snphi, csphi);
  330. shx := sinh(xi);
  331. chx := cosh(xi);
  332. x := sn * shx * csphi; // x = a*sin(eta)*sinh(xi)*cos(phi)
  333. y := sn * shx * snphi; // y = a*sin(eta)*sinh(xi)*sin(phi)
  334. z := cs * chx; // z = a*cos(eta)*cosh(xi)
  335. end;
  336. // ----- ProlateSpheroidal_Cartesian -------------------------------------------
  337. procedure ProlateSpheroidal_Cartesian(const xi,eta,phi,a:single;
  338. var x,y,z:single; var ierr:integer);overload;
  339. var
  340. sn, cs, snphi, csphi, shx, chx: single;
  341. begin
  342. if (xi < 0.0) then
  343. ierr := 1
  344. else if ((eta < 0.0) or (eta > pi)) then
  345. ierr := 2
  346. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  347. ierr := 3
  348. else
  349. ierr := 0;
  350. if (ierr = 0) then
  351. begin
  352. SinCosine(eta, a, sn, cs);
  353. SinCosine(phi, snphi, csphi);
  354. shx := sinh(xi);
  355. chx := cosh(xi);
  356. x := sn * shx * csphi; // x = a*sin(eta)*sinh(xi)*cos(phi)
  357. y := sn * shx * snphi; // y = a*sin(eta)*sinh(xi)*sin(phi)
  358. z := cs * chx; // z = a*cos(eta)*cosh(xi)
  359. end;
  360. end;
  361. // ----- ProlateSpheroidal_Cartesian -------------------------------------------
  362. procedure ProlateSpheroidal_Cartesian(const xi,eta,phi,a:double;
  363. var x,y,z:double; var ierr:integer);overload;
  364. var
  365. sn, cs, snphi, csphi, shx, chx: double;
  366. begin
  367. if (xi < 0.0) then
  368. ierr := 1
  369. else if ((eta < 0.0) or (eta > pi)) then
  370. ierr := 2
  371. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  372. ierr := 3
  373. else
  374. ierr := 0;
  375. if (ierr = 0) then
  376. begin
  377. SinCosine(eta, a, sn, cs);
  378. SinCosine(phi, snphi, csphi);
  379. shx := sinh(xi);
  380. chx := cosh(xi);
  381. x := sn * shx * csphi; // x = a*sin(eta)*sinh(xi)*cos(phi)
  382. y := sn * shx * snphi; // y = a*sin(eta)*sinh(xi)*sin(phi)
  383. z := cs * chx; // z = a*cos(eta)*cosh(xi)
  384. end;
  385. end;
  386. // ----- OblateSpheroidal_Cartesian -------------------------------------------
  387. procedure OblateSpheroidal_Cartesian(const xi,eta,phi,a:single;var x,y,z:single);
  388. var
  389. sn, cs, snphi, csphi, shx, chx: single;
  390. begin
  391. SinCosine(eta, a, sn, cs);
  392. SinCosine(phi, snphi, csphi);
  393. shx := sinh(xi);
  394. chx := cosh(xi);
  395. x := cs * chx * csphi; // x = a*cos(eta)*cosh(xi)*cos(phi)
  396. y := cs * chx * snphi; // y = a*cos(eta)*cosh(xi)*sin(phi)
  397. z := sn * shx; // z = a*sin(eta)*sinh(xi)
  398. end;
  399. // ----- OblateSpheroidal_Cartesian -------------------------------------------
  400. procedure OblateSpheroidal_Cartesian(const xi,eta,phi,a:double;var x,y,z:double);
  401. var
  402. sn,cs,snphi,csphi,shx,chx : double;
  403. begin
  404. SinCosine(eta,a,sn,cs);
  405. SinCosine(phi,snphi,csphi);
  406. shx := sinh(xi);
  407. chx := cosh(xi);
  408. x := cs * chx * csphi; // x = a*cos(eta)*cosh(xi)*cos(phi)
  409. y := cs * chx * snphi; // y = a*cos(eta)*cosh(xi)*sin(phi)
  410. z := sn * shx; // z = a*sin(eta)*sinh(xi)
  411. end;
  412. // ----- OblateSpheroidal_Cartesian -------------------------------------------
  413. procedure OblateSpheroidal_Cartesian(const xi,eta,phi,a:single;
  414. var x,y,z:single; var ierr:integer);overload;
  415. var
  416. sn, cs, snphi, csphi, shx, chx: single;
  417. begin
  418. if (xi < 0.0) then
  419. ierr := 1
  420. else if ((eta < -0.5 * pi) or (eta > 0.5 * pi)) then
  421. ierr := 2
  422. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  423. ierr := 3
  424. else
  425. ierr := 0;
  426. if (ierr = 0) then
  427. begin
  428. SinCosine(eta, a, sn, cs);
  429. SinCosine(phi, snphi, csphi);
  430. shx := sinh(xi);
  431. chx := cosh(xi);
  432. x := cs * chx * csphi; // x = a*cos(eta)*cosh(xi)*cos(phi)
  433. y := cs * chx * snphi; // y = a*cos(eta)*cosh(xi)*sin(phi)
  434. z := sn * shx; // z = a*sin(eta)*sinh(xi)
  435. end;
  436. end;
  437. // ----- OblateSpheroidal_Cartesian -------------------------------------------
  438. procedure OblateSpheroidal_Cartesian(const xi, eta, phi, a: double;
  439. var x, y, z: double; var ierr: integer); overload;
  440. var
  441. sn, cs, snphi, csphi, shx, chx: double;
  442. begin
  443. if (xi < 0.0) then
  444. ierr := 1
  445. else if ((eta < -0.5 * pi) or (eta > 0.5 * pi)) then
  446. ierr := 2
  447. else if ((phi < 0.0) or (phi >= 2 * pi)) then
  448. ierr := 3
  449. else
  450. ierr := 0;
  451. if (ierr = 0) then
  452. begin
  453. SinCosine(eta, a, sn, cs);
  454. SinCosine(phi, snphi, csphi);
  455. shx := sinh(xi);
  456. chx := cosh(xi);
  457. x := cs * chx * csphi; // x = a*cos(eta)*cosh(xi)*cos(phi)
  458. y := cs * chx * snphi; // y = a*cos(eta)*cosh(xi)*sin(phi)
  459. z := sn * shx; // z = a*sin(eta)*sinh(xi)
  460. end;
  461. end;
  462. // ----- BipolarCylindrical_Cartesian ------------------------------------------
  463. procedure BipolarCylindrical_Cartesian(const u,v,z1,a:single;var x,y,z:single);
  464. var
  465. cs, sn, shx, chx: single;
  466. begin
  467. SinCosine(u, sn, cs);
  468. shx := sinh(v);
  469. chx := cosh(v);
  470. x := a * shx / (chx - cs);
  471. y := a * sn / (chx - cs);
  472. z := z1;
  473. end;
  474. // ----- BipolarCylindrical_Cartesian ------------------------------------------
  475. procedure BipolarCylindrical_Cartesian(const u,v,z1,a:double;var x,y,z:double);
  476. var
  477. cs, sn, shx, chx: double;
  478. begin
  479. SinCosine(u, sn, cs);
  480. shx := sinh(v);
  481. chx := cosh(v);
  482. x := a * shx / (chx - cs);
  483. y := a * sn / (chx - cs);
  484. z := z1;
  485. end;
  486. // ----- BipolarCylindrical_Cartesian ------------------------------------------
  487. procedure BipolarCylindrical_Cartesian(const u,v,z1,a:single;
  488. var x,y,z:single; var ierr:integer);overload;
  489. var
  490. cs, sn, shx, chx: single;
  491. begin
  492. if ((u < 0.0) or (u >= 2 * pi)) then
  493. ierr := 1
  494. else
  495. ierr := 0;
  496. if (ierr = 0) then
  497. begin
  498. SinCosine(u, sn, cs);
  499. shx := sinh(v);
  500. chx := cosh(v);
  501. x := a * shx / (chx - cs);
  502. y := a * sn / (chx - cs);
  503. z := z1;
  504. end;
  505. end;
  506. // ----- BipolarCylindrical_Cartesian ------------------------------------------
  507. procedure BipolarCylindrical_Cartesian(const u,v,z1,a:double;
  508. var x,y,z:double; var ierr:integer);overload;
  509. var
  510. cs, sn, shx, chx: double;
  511. begin
  512. if ((u < 0.0) or (u >= 2 * pi)) then
  513. ierr := 1
  514. else
  515. ierr := 0;
  516. if (ierr = 0) then
  517. begin
  518. SinCosine(u, sn, cs);
  519. shx := sinh(v);
  520. chx := cosh(v);
  521. x := a * shx / (chx - cs);
  522. y := a * sn / (chx - cs);
  523. z := z1;
  524. end;
  525. end;
  526. // =============================================================================
  527. end.