MATRICES.C 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. /****************************************************************************
  2. * matrices.c
  3. *
  4. * This module contains code to manipulate 4x4 matrices.
  5. *
  6. * from Persistence of Vision(tm) Ray Tracer
  7. * Copyright 1996,1999 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. * NOTICE: This source code file is provided so that users may experiment
  10. * with enhancements to POV-Ray and to port the software to platforms other
  11. * than those supported by the POV-Ray Team. There are strict rules under
  12. * which you are permitted to use this file. The rules are in the file
  13. * named POVLEGAL.DOC which should be distributed with this file.
  14. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  16. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23. #include "frame.h"
  24. #include "vector.h"
  25. #include "povproto.h"
  26. #include "matrices.h"
  27. /*****************************************************************************
  28. * Local preprocessor defines
  29. ******************************************************************************/
  30. /*****************************************************************************
  31. * Local typedefs
  32. ******************************************************************************/
  33. /*****************************************************************************
  34. * Local variables
  35. ******************************************************************************/
  36. /*****************************************************************************
  37. * Static functions
  38. ******************************************************************************/
  39. /*****************************************************************************
  40. *
  41. * FUNCTION
  42. *
  43. * INPUT
  44. *
  45. * OUTPUT
  46. *
  47. * RETURNS
  48. *
  49. * AUTHOR
  50. *
  51. * POV-Ray Team
  52. *
  53. * DESCRIPTION
  54. *
  55. * Initialize the matrix to the following values:
  56. *
  57. * 0.0 0.0 0.0 0.0
  58. * 0.0 0.0 0.0 0.0
  59. * 0.0 0.0 0.0 0.0
  60. * 0.0 0.0 0.0 0.0
  61. *
  62. * CHANGES
  63. *
  64. * -
  65. *
  66. ******************************************************************************/
  67. void MZero (MATRIX result)
  68. {
  69. register int i, j;
  70. for (i = 0 ; i < 4 ; i++)
  71. {
  72. for (j = 0 ; j < 4 ; j++)
  73. {
  74. result[i][j] = 0.0;
  75. }
  76. }
  77. }
  78. /*****************************************************************************
  79. *
  80. * FUNCTION
  81. *
  82. * INPUT
  83. *
  84. * OUTPUT
  85. *
  86. * RETURNS
  87. *
  88. * AUTHOR
  89. *
  90. * POV-Ray Team
  91. *
  92. * DESCRIPTION
  93. *
  94. * Initialize the matrix to the following values:
  95. *
  96. * 1.0 0.0 0.0 0.0
  97. * 0.0 1.0 0.0 0.0
  98. * 0.0 0.0 1.0 0.0
  99. * 0.0 0.0 0.0 1.0
  100. *
  101. * CHANGES
  102. *
  103. * -
  104. *
  105. ******************************************************************************/
  106. void MIdentity (MATRIX result)
  107. {
  108. register int i, j;
  109. for (i = 0 ; i < 4 ; i++)
  110. {
  111. for (j = 0 ; j < 4 ; j++)
  112. {
  113. if (i == j)
  114. {
  115. result[i][j] = 1.0;
  116. }
  117. else
  118. {
  119. result[i][j] = 0.0;
  120. }
  121. }
  122. }
  123. }
  124. /*****************************************************************************
  125. *
  126. * FUNCTION
  127. *
  128. * INPUT
  129. *
  130. * OUTPUT
  131. *
  132. * RETURNS
  133. *
  134. * AUTHOR
  135. *
  136. * POV-Ray Team
  137. *
  138. * DESCRIPTION
  139. *
  140. * -
  141. *
  142. * CHANGES
  143. *
  144. * -
  145. *
  146. ******************************************************************************/
  147. void MTimes (MATRIX result, MATRIX matrix1, MATRIX matrix2)
  148. {
  149. register int i, j, k;
  150. MATRIX temp_matrix;
  151. for (i = 0 ; i < 4 ; i++)
  152. {
  153. for (j = 0 ; j < 4 ; j++)
  154. {
  155. temp_matrix[i][j] = 0.0;
  156. for (k = 0 ; k < 4 ; k++)
  157. {
  158. temp_matrix[i][j] += matrix1[i][k] * matrix2[k][j];
  159. }
  160. }
  161. }
  162. for (i = 0 ; i < 4 ; i++)
  163. {
  164. for (j = 0 ; j < 4 ; j++)
  165. {
  166. result[i][j] = temp_matrix[i][j];
  167. }
  168. }
  169. }
  170. /* AAC - These are not used, so they are commented out to save code space...
  171. void MAdd (MATRIX result, MATRIX matrix1, MATRIX matrix2)
  172. {
  173. register int i, j;
  174. for (i = 0 ; i < 4 ; i++)
  175. for (j = 0 ; j < 4 ; j++)
  176. result[i][j] = (*matrix1)[i][j] + (*matrix2)[i][j];
  177. }
  178. void MSub (MATRIX result, MATRIX matrix1, MATRIX matrix2)
  179. {
  180. register int i, j;
  181. for (i = 0 ; i < 4 ; i++)
  182. for (j = 0 ; j < 4 ; j++)
  183. result[i][j] = matrix1[i][j] - matrix2[i][j];
  184. }
  185. void MScale (MATRIX result, MATRIX matrix1, DBL amount)
  186. {
  187. register int i, j;
  188. for (i = 0 ; i < 4 ; i++)
  189. for (j = 0 ; j < 4 ; j++)
  190. result[i][j] = matrix1[i][j] * amount;
  191. }
  192. ... up to here! */
  193. /*****************************************************************************
  194. *
  195. * FUNCTION
  196. *
  197. * INPUT
  198. *
  199. * OUTPUT
  200. *
  201. * RETURNS
  202. *
  203. * AUTHOR
  204. *
  205. * POV-Ray Team
  206. *
  207. * DESCRIPTION
  208. *
  209. * -
  210. *
  211. * CHANGES
  212. *
  213. * -
  214. *
  215. ******************************************************************************/
  216. void MTranspose (MATRIX result, MATRIX matrix1)
  217. {
  218. register int i, j;
  219. MATRIX temp_matrix;
  220. for (i = 0 ; i < 4 ; i++)
  221. {
  222. for (j = 0 ; j < 4 ; j++)
  223. {
  224. temp_matrix[i][j] = matrix1[j][i];
  225. }
  226. }
  227. for (i = 0 ; i < 4 ; i++)
  228. {
  229. for (j = 0 ; j < 4 ; j++)
  230. {
  231. result[i][j] = temp_matrix[i][j];
  232. }
  233. }
  234. }
  235. /*****************************************************************************
  236. *
  237. * FUNCTION
  238. *
  239. * INPUT
  240. *
  241. * OUTPUT
  242. *
  243. * RETURNS
  244. *
  245. * AUTHOR
  246. *
  247. * POV-Ray Team
  248. *
  249. * DESCRIPTION
  250. *
  251. * -
  252. *
  253. * CHANGES
  254. *
  255. * Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  256. *
  257. ******************************************************************************/
  258. void MTransPoint (VECTOR result, VECTOR vector, TRANSFORM *transform)
  259. {
  260. register int i;
  261. DBL answer_array[4];
  262. MATRIX *matrix;
  263. matrix = (MATRIX *) transform->matrix;
  264. for (i = 0 ; i < 3 ; i++)
  265. {
  266. answer_array[i] = vector[X] * (*matrix)[0][i] +
  267. vector[Y] * (*matrix)[1][i] +
  268. vector[Z] * (*matrix)[2][i] + (*matrix)[3][i];
  269. }
  270. result[X] = answer_array[0];
  271. result[Y] = answer_array[1];
  272. result[Z] = answer_array[2];
  273. }
  274. /*****************************************************************************
  275. *
  276. * FUNCTION
  277. *
  278. * INPUT
  279. *
  280. * OUTPUT
  281. *
  282. * RETURNS
  283. *
  284. * AUTHOR
  285. *
  286. * POV-Ray Team
  287. *
  288. * DESCRIPTION
  289. *
  290. * -
  291. *
  292. * CHANGES
  293. *
  294. * Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  295. *
  296. ******************************************************************************/
  297. void MInvTransPoint (VECTOR result, VECTOR vector, TRANSFORM *transform)
  298. {
  299. register int i;
  300. DBL answer_array[4];
  301. MATRIX *matrix;
  302. matrix = (MATRIX *) transform->inverse;
  303. for (i = 0 ; i < 3 ; i++)
  304. {
  305. answer_array[i] = vector[X] * (*matrix)[0][i] +
  306. vector[Y] * (*matrix)[1][i] +
  307. vector[Z] * (*matrix)[2][i] + (*matrix)[3][i];
  308. }
  309. result[X] = answer_array[0];
  310. result[Y] = answer_array[1];
  311. result[Z] = answer_array[2];
  312. }
  313. /*****************************************************************************
  314. *
  315. * FUNCTION
  316. *
  317. * INPUT
  318. *
  319. * OUTPUT
  320. *
  321. * RETURNS
  322. *
  323. * AUTHOR
  324. *
  325. * POV-Ray Team
  326. *
  327. * DESCRIPTION
  328. *
  329. * -
  330. *
  331. * CHANGES
  332. *
  333. * Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  334. *
  335. ******************************************************************************/
  336. void MTransDirection (VECTOR result, VECTOR vector, TRANSFORM *transform)
  337. {
  338. register int i;
  339. DBL answer_array[4];
  340. MATRIX *matrix;
  341. matrix = (MATRIX *) transform->matrix;
  342. for (i = 0 ; i < 3 ; i++)
  343. {
  344. answer_array[i] = vector[X] * (*matrix)[0][i] +
  345. vector[Y] * (*matrix)[1][i] +
  346. vector[Z] * (*matrix)[2][i];
  347. }
  348. result[X] = answer_array[0];
  349. result[Y] = answer_array[1];
  350. result[Z] = answer_array[2];
  351. }
  352. /*****************************************************************************
  353. *
  354. * FUNCTION
  355. *
  356. * INPUT
  357. *
  358. * OUTPUT
  359. *
  360. * RETURNS
  361. *
  362. * AUTHOR
  363. *
  364. * POV-Ray Team
  365. *
  366. * DESCRIPTION
  367. *
  368. * -
  369. *
  370. * CHANGES
  371. *
  372. * Sep 1994 : Modified to not calculate anser_array[3]. [DB]
  373. *
  374. ******************************************************************************/
  375. void MInvTransDirection (VECTOR result, VECTOR vector, TRANSFORM *transform)
  376. {
  377. register int i;
  378. DBL answer_array[4];
  379. MATRIX *matrix;
  380. matrix = (MATRIX *) transform->inverse;
  381. for (i = 0 ; i < 3 ; i++)
  382. {
  383. answer_array[i] = vector[X] * (*matrix)[0][i] +
  384. vector[Y] * (*matrix)[1][i] +
  385. vector[Z] * (*matrix)[2][i];
  386. }
  387. result[X] = answer_array[0];
  388. result[Y] = answer_array[1];
  389. result[Z] = answer_array[2];
  390. }
  391. /*****************************************************************************
  392. *
  393. * FUNCTION
  394. *
  395. * INPUT
  396. *
  397. * OUTPUT
  398. *
  399. * RETURNS
  400. *
  401. * AUTHOR
  402. *
  403. * POV-Ray Team
  404. *
  405. * DESCRIPTION
  406. *
  407. * -
  408. *
  409. * CHANGES
  410. *
  411. * -
  412. *
  413. ******************************************************************************/
  414. void MTransNormal (VECTOR result, VECTOR vector, TRANSFORM *transform)
  415. {
  416. register int i;
  417. DBL answer_array[3];
  418. MATRIX *matrix;
  419. matrix = (MATRIX *) transform->inverse;
  420. for (i = 0 ; i < 3 ; i++)
  421. {
  422. answer_array[i] = vector[X] * (*matrix)[i][0] +
  423. vector[Y] * (*matrix)[i][1] +
  424. vector[Z] * (*matrix)[i][2];
  425. }
  426. result[X] = answer_array[0];
  427. result[Y] = answer_array[1];
  428. result[Z] = answer_array[2];
  429. }
  430. /*****************************************************************************
  431. *
  432. * FUNCTION
  433. *
  434. * INPUT
  435. *
  436. * OUTPUT
  437. *
  438. * RETURNS
  439. *
  440. * AUTHOR
  441. *
  442. * POV-Ray Team
  443. *
  444. * DESCRIPTION
  445. *
  446. * -
  447. *
  448. * CHANGES
  449. *
  450. * -
  451. *
  452. ******************************************************************************/
  453. void MInvTransNormal (VECTOR result, VECTOR vector, TRANSFORM *transform)
  454. {
  455. register int i;
  456. DBL answer_array[3];
  457. MATRIX *matrix;
  458. matrix = (MATRIX *) transform->matrix;
  459. for (i = 0 ; i < 3 ; i++)
  460. {
  461. answer_array[i] = vector[X] * (*matrix)[i][0] +
  462. vector[Y] * (*matrix)[i][1] +
  463. vector[Z] * (*matrix)[i][2];
  464. }
  465. result[X] = answer_array[0];
  466. result[Y] = answer_array[1];
  467. result[Z] = answer_array[2];
  468. }
  469. /*****************************************************************************
  470. *
  471. * FUNCTION
  472. *
  473. * INPUT
  474. *
  475. * OUTPUT
  476. *
  477. * RETURNS
  478. *
  479. * AUTHOR
  480. *
  481. * POV-Ray Team
  482. *
  483. * DESCRIPTION
  484. *
  485. * -
  486. *
  487. * CHANGES
  488. *
  489. * -
  490. *
  491. ******************************************************************************/
  492. void Compute_Scaling_Transform (TRANSFORM *result, VECTOR vector)
  493. {
  494. MIdentity (result->matrix);
  495. (result->matrix)[0][0] = vector[X];
  496. (result->matrix)[1][1] = vector[Y];
  497. (result->matrix)[2][2] = vector[Z];
  498. MIdentity (result->inverse);
  499. (result->inverse)[0][0] = 1.0 / vector[X];
  500. (result->inverse)[1][1] = 1.0 / vector[Y];
  501. (result->inverse)[2][2] = 1.0 / vector[Z];
  502. }
  503. /*****************************************************************************
  504. *
  505. * FUNCTION
  506. *
  507. * Compute_Matrix_Transform
  508. *
  509. * INPUT
  510. *
  511. * matrix - matrix from which to create transform
  512. *
  513. * OUTPUT
  514. *
  515. * result - complete transform
  516. *
  517. * RETURNS
  518. *
  519. * AUTHOR
  520. *
  521. * POV-Ray Team
  522. *
  523. * DESCRIPTION
  524. *
  525. * Builds a complete transform from a matrix.
  526. *
  527. * CHANGES
  528. *
  529. * June 1995 : Creation
  530. *
  531. ******************************************************************************/
  532. void Compute_Matrix_Transform (TRANSFORM *result, MATRIX matrix)
  533. {
  534. register int i;
  535. for (i = 0; i < 4; i++)
  536. {
  537. (result->matrix)[i][0] = matrix[i][0];
  538. (result->matrix)[i][1] = matrix[i][1];
  539. (result->matrix)[i][2] = matrix[i][2];
  540. (result->matrix)[i][3] = matrix[i][3];
  541. }
  542. MInvers(result->inverse, result->matrix);
  543. }
  544. /* AAC - This is not used, so it's commented out...
  545. void Compute_Inversion_Transform (TRANSFORM *result)
  546. {
  547. MIdentity (result->matrix);
  548. (result->matrix)[0][0] = -1.0;
  549. (result->matrix)[1][1] = -1.0;
  550. (result->matrix)[2][2] = -1.0;
  551. (result->matrix)[3][3] = -1.0;
  552. (result->inverse)[0][0] = -1.0;
  553. (result->inverse)[1][1] = -1.0;
  554. (result->inverse)[2][2] = -1.0;
  555. (result->inverse)[3][3] = -1.0;
  556. }
  557. ... up to here! */
  558. /*****************************************************************************
  559. *
  560. * FUNCTION
  561. *
  562. * INPUT
  563. *
  564. * OUTPUT
  565. *
  566. * RETURNS
  567. *
  568. * AUTHOR
  569. *
  570. * POV-Ray Team
  571. *
  572. * DESCRIPTION
  573. *
  574. * -
  575. *
  576. * CHANGES
  577. *
  578. * -
  579. *
  580. ******************************************************************************/
  581. void Compute_Translation_Transform (TRANSFORM *transform, VECTOR vector)
  582. {
  583. MIdentity (transform->matrix);
  584. (transform->matrix)[3][0] = vector[X];
  585. (transform->matrix)[3][1] = vector[Y];
  586. (transform->matrix)[3][2] = vector[Z];
  587. MIdentity (transform->inverse);
  588. (transform->inverse)[3][0] = -vector[X];
  589. (transform->inverse)[3][1] = -vector[Y];
  590. (transform->inverse)[3][2] = -vector[Z];
  591. }
  592. /*****************************************************************************
  593. *
  594. * FUNCTION
  595. *
  596. * INPUT
  597. *
  598. * OUTPUT
  599. *
  600. * RETURNS
  601. *
  602. * AUTHOR
  603. *
  604. * POV-Ray Team
  605. *
  606. * DESCRIPTION
  607. *
  608. * -
  609. *
  610. * CHANGES
  611. *
  612. * -
  613. *
  614. ******************************************************************************/
  615. void Compute_Rotation_Transform (TRANSFORM *transform, VECTOR vector)
  616. {
  617. register DBL cosx, cosy, cosz, sinx, siny, sinz;
  618. MATRIX Matrix;
  619. VECTOR Radian_Vector;
  620. VScale (Radian_Vector, vector, M_PI_180);
  621. MIdentity (transform->matrix);
  622. cosx = cos (Radian_Vector[X]);
  623. sinx = sin (Radian_Vector[X]);
  624. cosy = cos (Radian_Vector[Y]);
  625. siny = sin (Radian_Vector[Y]);
  626. cosz = cos (Radian_Vector[Z]);
  627. sinz = sin (Radian_Vector[Z]);
  628. (transform->matrix) [1][1] = cosx;
  629. (transform->matrix) [2][2] = cosx;
  630. (transform->matrix) [1][2] = sinx;
  631. (transform->matrix) [2][1] = 0.0 - sinx;
  632. MTranspose (transform->inverse, transform->matrix);
  633. MIdentity (Matrix);
  634. Matrix [0][0] = cosy;
  635. Matrix [2][2] = cosy;
  636. Matrix [0][2] = 0.0 - siny;
  637. Matrix [2][0] = siny;
  638. MTimes (transform->matrix, transform->matrix, Matrix);
  639. MTranspose (Matrix, Matrix);
  640. MTimes (transform->inverse, Matrix, transform->inverse);
  641. MIdentity (Matrix);
  642. Matrix [0][0] = cosz;
  643. Matrix [1][1] = cosz;
  644. Matrix [0][1] = sinz;
  645. Matrix [1][0] = 0.0 - sinz;
  646. MTimes (transform->matrix, transform->matrix, Matrix);
  647. MTranspose (Matrix, Matrix);
  648. MTimes (transform->inverse, Matrix, transform->inverse);
  649. }
  650. /* AAC - This is not used so it's commented out...
  651. void Compute_Look_At_Transform (TRANSFORM *result, VECTOR Look_At, VECTOR Up, VECTOR Right)
  652. {
  653. MIdentity (result->inverse);
  654. (result->matrix)[0][0] = Right[X];
  655. (result->matrix)[0][1] = Right[Y];
  656. (result->matrix)[0][2] = Right[Z];
  657. (result->matrix)[1][0] = Up[X];
  658. (result->matrix)[1][1] = Up[Y];
  659. (result->matrix)[1][2] = Up[Z];
  660. (result->matrix)[2][0] = Look_At[X];
  661. (result->matrix)[2][1] = Look_At[Y];
  662. (result->matrix)[2][2] = Look_At[Z];
  663. MIdentity (result->matrix);
  664. MTranspose (result->matrix, result->inverse);
  665. }
  666. ... up to here! */
  667. /*****************************************************************************
  668. *
  669. * FUNCTION
  670. *
  671. * INPUT
  672. *
  673. * OUTPUT
  674. *
  675. * RETURNS
  676. *
  677. * AUTHOR
  678. *
  679. * POV-Ray Team
  680. *
  681. * DESCRIPTION
  682. *
  683. * -
  684. *
  685. * CHANGES
  686. *
  687. * -
  688. *
  689. ******************************************************************************/
  690. void Compose_Transforms (TRANSFORM *Original_Transform, TRANSFORM *New_Transform)
  691. {
  692. MTimes(Original_Transform->matrix, Original_Transform->matrix, New_Transform->matrix);
  693. MTimes(Original_Transform->inverse, New_Transform->inverse, Original_Transform->inverse);
  694. }
  695. /*****************************************************************************
  696. *
  697. * FUNCTION
  698. *
  699. * INPUT
  700. *
  701. * OUTPUT
  702. *
  703. * RETURNS
  704. *
  705. * AUTHOR
  706. *
  707. * POV-Ray Team
  708. *
  709. * DESCRIPTION
  710. *
  711. * Rotation about an arbitrary axis - formula from:
  712. *
  713. * "Computational Geometry for Design and Manufacture", Faux & Pratt
  714. *
  715. * NOTE: The angles for this transform are specified in radians.
  716. *
  717. * CHANGES
  718. *
  719. * -
  720. *
  721. ******************************************************************************/
  722. void Compute_Axis_Rotation_Transform (TRANSFORM *transform, VECTOR V1, DBL angle)
  723. {
  724. DBL l, cosx, sinx;
  725. VLength(l, V1);
  726. VInverseScaleEq(V1, l);
  727. MIdentity(transform->matrix);
  728. cosx = cos(angle);
  729. sinx = sin(angle);
  730. transform->matrix[0][0] = V1[X] * V1[X] + cosx * (1.0 - V1[X] * V1[X]);
  731. transform->matrix[0][1] = V1[X] * V1[Y] * (1.0 - cosx) + V1[Z] * sinx;
  732. transform->matrix[0][2] = V1[X] * V1[Z] * (1.0 - cosx) - V1[Y] * sinx;
  733. transform->matrix[1][0] = V1[X] * V1[Y] * (1.0 - cosx) - V1[Z] * sinx;
  734. transform->matrix[1][1] = V1[Y] * V1[Y] + cosx * (1.0 - V1[Y] * V1[Y]);
  735. transform->matrix[1][2] = V1[Y] * V1[Z] * (1.0 - cosx) + V1[X] * sinx;
  736. transform->matrix[2][0] = V1[X] * V1[Z] * (1.0 - cosx) + V1[Y] * sinx;
  737. transform->matrix[2][1] = V1[Y] * V1[Z] * (1.0 - cosx) - V1[X] * sinx;
  738. transform->matrix[2][2] = V1[Z] * V1[Z] + cosx * (1.0 - V1[Z] * V1[Z]);
  739. MTranspose(transform->inverse, transform->matrix);
  740. }
  741. /*****************************************************************************
  742. *
  743. * FUNCTION
  744. *
  745. * INPUT
  746. *
  747. * OUTPUT
  748. *
  749. * RETURNS
  750. *
  751. * AUTHOR
  752. *
  753. * POV-Ray Team
  754. *
  755. * DESCRIPTION
  756. *
  757. * Given a point and a direction and a radius, find the transform
  758. * that brings these into a canonical coordinate system
  759. *
  760. * CHANGES
  761. *
  762. * 7/24/95 Eduard Schwan - Changed "if" condition to use EPSILON, not equality
  763. * 12/12/95 Steve Demlow - Clipped abs(up[Z]) to 1 to avoid acos overflow
  764. *
  765. ******************************************************************************/
  766. void Compute_Coordinate_Transform(TRANSFORM *trans, VECTOR origin, VECTOR up, DBL radius, DBL length)
  767. {
  768. TRANSFORM trans2;
  769. VECTOR tmpv;
  770. Make_Vector(tmpv, radius, radius, length);
  771. Compute_Scaling_Transform(trans, tmpv);
  772. if (fabs(up[Z]) > 1.0 - EPSILON)
  773. {
  774. Make_Vector(tmpv, 1.0, 0.0, 0.0)
  775. up[Z] = up[Z] < 0.0 ? -1.0 : 1.0;
  776. }
  777. else
  778. {
  779. Make_Vector(tmpv, -up[Y], up[X], 0.0)
  780. }
  781. Compute_Axis_Rotation_Transform(&trans2, tmpv, acos(up[Z]));
  782. Compose_Transforms(trans, &trans2);
  783. Compute_Translation_Transform(&trans2, origin);
  784. Compose_Transforms(trans, &trans2);
  785. }
  786. /*****************************************************************************
  787. *
  788. * FUNCTION
  789. *
  790. * INPUT
  791. *
  792. * OUTPUT
  793. *
  794. * RETURNS
  795. *
  796. * AUTHOR
  797. *
  798. * POV-Ray Team
  799. *
  800. * DESCRIPTION
  801. *
  802. * -
  803. *
  804. * CHANGES
  805. *
  806. * -
  807. *
  808. ******************************************************************************/
  809. TRANSFORM *Create_Transform()
  810. {
  811. TRANSFORM *New;
  812. New = (TRANSFORM *)POV_MALLOC(sizeof (TRANSFORM), "transform");
  813. MIdentity (New->matrix);
  814. MIdentity (New->inverse);
  815. return (New);
  816. }
  817. /*****************************************************************************
  818. *
  819. * FUNCTION
  820. *
  821. * INPUT
  822. *
  823. * OUTPUT
  824. *
  825. * RETURNS
  826. *
  827. * AUTHOR
  828. *
  829. * POV-Ray Team
  830. *
  831. * DESCRIPTION
  832. *
  833. * -
  834. *
  835. * CHANGES
  836. *
  837. * -
  838. *
  839. ******************************************************************************/
  840. TRANSFORM *Copy_Transform (TRANSFORM *Old)
  841. {
  842. TRANSFORM *New;
  843. if (Old != NULL)
  844. {
  845. New = Create_Transform ();
  846. *New = *Old;
  847. }
  848. else
  849. {
  850. New = NULL;
  851. }
  852. return (New);
  853. }
  854. /*****************************************************************************
  855. *
  856. * FUNCTION
  857. *
  858. * INPUT
  859. *
  860. * OUTPUT
  861. *
  862. * RETURNS
  863. *
  864. * AUTHOR
  865. *
  866. * POV-Ray Team
  867. *
  868. * DESCRIPTION
  869. *
  870. * -
  871. *
  872. * CHANGES
  873. *
  874. * -
  875. *
  876. ******************************************************************************/
  877. VECTOR *Create_Vector ()
  878. {
  879. VECTOR *New;
  880. New = (VECTOR *)POV_MALLOC(sizeof (VECTOR), "vector");
  881. Make_Vector (*New, 0.0, 0.0, 0.0);
  882. return (New);
  883. }
  884. /*****************************************************************************
  885. *
  886. * FUNCTION
  887. *
  888. * INPUT
  889. *
  890. * OUTPUT
  891. *
  892. * RETURNS
  893. *
  894. * AUTHOR
  895. *
  896. * POV-Ray Team
  897. *
  898. * DESCRIPTION
  899. *
  900. * -
  901. *
  902. * CHANGES
  903. *
  904. * -
  905. *
  906. ******************************************************************************/
  907. DBL *Create_Float ()
  908. {
  909. DBL *New_Float;
  910. New_Float = (DBL *)POV_MALLOC(sizeof (DBL), "float");
  911. *New_Float = 0.0;
  912. return (New_Float);
  913. }
  914. /*****************************************************************************
  915. *
  916. * FUNCTION
  917. *
  918. * MInvers
  919. *
  920. * INPUT
  921. *
  922. * m - matrix to invert
  923. * r - inverted matrix
  924. *
  925. * OUTPUT
  926. *
  927. * r
  928. *
  929. * RETURNS
  930. *
  931. * AUTHOR
  932. *
  933. * Dieter Bayer
  934. *
  935. * DESCRIPTION
  936. *
  937. * Invert a 4x4 matrix.
  938. *
  939. * CHANGES
  940. *
  941. * May 1994 : Creation.
  942. *
  943. ******************************************************************************/
  944. void MInvers(MATRIX r, MATRIX m)
  945. {
  946. DBL d00, d01, d02, d03;
  947. DBL d10, d11, d12, d13;
  948. DBL d20, d21, d22, d23;
  949. DBL d30, d31, d32, d33;
  950. DBL m00, m01, m02, m03;
  951. DBL m10, m11, m12, m13;
  952. DBL m20, m21, m22, m23;
  953. DBL m30, m31, m32, m33;
  954. DBL D;
  955. m00 = m[0][0]; m01 = m[0][1]; m02 = m[0][2]; m03 = m[0][3];
  956. m10 = m[1][0]; m11 = m[1][1]; m12 = m[1][2]; m13 = m[1][3];
  957. m20 = m[2][0]; m21 = m[2][1]; m22 = m[2][2]; m23 = m[2][3];
  958. m30 = m[3][0]; m31 = m[3][1]; m32 = m[3][2]; m33 = m[3][3];
  959. d00 = m11*m22*m33 + m12*m23*m31 + m13*m21*m32 - m31*m22*m13 - m32*m23*m11 - m33*m21*m12;
  960. d01 = m10*m22*m33 + m12*m23*m30 + m13*m20*m32 - m30*m22*m13 - m32*m23*m10 - m33*m20*m12;
  961. d02 = m10*m21*m33 + m11*m23*m30 + m13*m20*m31 - m30*m21*m13 - m31*m23*m10 - m33*m20*m11;
  962. d03 = m10*m21*m32 + m11*m22*m30 + m12*m20*m31 - m30*m21*m12 - m31*m22*m10 - m32*m20*m11;
  963. d10 = m01*m22*m33 + m02*m23*m31 + m03*m21*m32 - m31*m22*m03 - m32*m23*m01 - m33*m21*m02;
  964. d11 = m00*m22*m33 + m02*m23*m30 + m03*m20*m32 - m30*m22*m03 - m32*m23*m00 - m33*m20*m02;
  965. d12 = m00*m21*m33 + m01*m23*m30 + m03*m20*m31 - m30*m21*m03 - m31*m23*m00 - m33*m20*m01;
  966. d13 = m00*m21*m32 + m01*m22*m30 + m02*m20*m31 - m30*m21*m02 - m31*m22*m00 - m32*m20*m01;
  967. d20 = m01*m12*m33 + m02*m13*m31 + m03*m11*m32 - m31*m12*m03 - m32*m13*m01 - m33*m11*m02;
  968. d21 = m00*m12*m33 + m02*m13*m30 + m03*m10*m32 - m30*m12*m03 - m32*m13*m00 - m33*m10*m02;
  969. d22 = m00*m11*m33 + m01*m13*m30 + m03*m10*m31 - m30*m11*m03 - m31*m13*m00 - m33*m10*m01;
  970. d23 = m00*m11*m32 + m01*m12*m30 + m02*m10*m31 - m30*m11*m02 - m31*m12*m00 - m32*m10*m01;
  971. d30 = m01*m12*m23 + m02*m13*m21 + m03*m11*m22 - m21*m12*m03 - m22*m13*m01 - m23*m11*m02;
  972. d31 = m00*m12*m23 + m02*m13*m20 + m03*m10*m22 - m20*m12*m03 - m22*m13*m00 - m23*m10*m02;
  973. d32 = m00*m11*m23 + m01*m13*m20 + m03*m10*m21 - m20*m11*m03 - m21*m13*m00 - m23*m10*m01;
  974. d33 = m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m21*m12*m00 - m22*m10*m01;
  975. D = m00*d00 - m01*d01 + m02*d02 - m03*d03;
  976. if (D == 0.0)
  977. {
  978. Error("Singular matrix in MInvers.\n");
  979. }
  980. r[0][0] = d00/D; r[0][1] = -d10/D; r[0][2] = d20/D; r[0][3] = -d30/D;
  981. r[1][0] = -d01/D; r[1][1] = d11/D; r[1][2] = -d21/D; r[1][3] = d31/D;
  982. r[2][0] = d02/D; r[2][1] = -d12/D; r[2][2] = d22/D; r[2][3] = -d32/D;
  983. r[3][0] = -d03/D; r[3][1] = d13/D; r[3][2] = -d23/D; r[3][3] = d33/D;
  984. }
  985. UV_VECT *Create_UV_Vect ()
  986. {
  987. UV_VECT *New;
  988. New = (UV_VECT *)POV_MALLOC(sizeof (UV_VECT), "uv vector");
  989. (*New)[0]= 0.0;
  990. (*New)[1]= 0.0;
  991. return (New);
  992. }
  993. VECTOR_4D *Create_Vector_4D ()
  994. {
  995. VECTOR_4D *New;
  996. New = (VECTOR_4D *)POV_MALLOC(sizeof (VECTOR_4D), "4d vector");
  997. (*New)[0]= 0.0;
  998. (*New)[1]= 0.0;
  999. (*New)[2]= 0.0;
  1000. (*New)[3]= 0.0;
  1001. return (New);
  1002. }