CONES.C 19 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. /****************************************************************************
  2. * cones.c
  3. *
  4. * This module implements the cone primitive.
  5. * This file was written by Alexander Enzmann. He wrote the code for
  6. * cones and generously provided us these enhancements.
  7. *
  8. * from Persistence of Vision(tm) Ray Tracer
  9. * Copyright 1996,1999 Persistence of Vision Team
  10. *---------------------------------------------------------------------------
  11. * NOTICE: This source code file is provided so that users may experiment
  12. * with enhancements to POV-Ray and to port the software to platforms other
  13. * than those supported by the POV-Ray Team. There are strict rules under
  14. * which you are permitted to use this file. The rules are in the file
  15. * named POVLEGAL.DOC which should be distributed with this file.
  16. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  17. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  18. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  19. *
  20. * This program is based on the popular DKB raytracer version 2.12.
  21. * DKBTrace was originally written by David K. Buck.
  22. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  23. *
  24. *****************************************************************************/
  25. #include "frame.h"
  26. #include "povray.h"
  27. #include "vector.h"
  28. #include "povproto.h"
  29. #include "bbox.h"
  30. #include "cones.h"
  31. #include "matrices.h"
  32. #include "objects.h"
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36. #define Cone_Tolerance 1.0e-6
  37. #define close(x, y) (fabs(x-y) < EPSILON ? 1 : 0)
  38. /* Part of the cone/cylinder hit. [DB 9/94] */
  39. #define BASE_HIT 1
  40. #define CAP_HIT 2
  41. #define SIDE_HIT 3
  42. /*****************************************************************************
  43. * Local typedefs
  44. ******************************************************************************/
  45. typedef struct Cone_Intersection_Structure CONE_INT;
  46. struct Cone_Intersection_Structure
  47. {
  48. DBL d; /* Distance of intersection point */
  49. int t; /* Type of intersection: base/cap plane or side */
  50. };
  51. /*****************************************************************************
  52. * Static functions
  53. ******************************************************************************/
  54. static int intersect_cone (RAY *Ray, CONE *Cone, CONE_INT *Depths);
  55. static void Destroy_Cone (OBJECT *Object);
  56. static int All_Cone_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  57. static int Inside_Cone (VECTOR point, OBJECT *Object);
  58. static void Cone_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  59. static CONE *Copy_Cone (OBJECT *Object);
  60. static void Translate_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  61. static void Rotate_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  62. static void Scale_Cone (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  63. static void Transform_Cone (OBJECT *Object, TRANSFORM *Trans);
  64. static void Invert_Cone (OBJECT *Object);
  65. /*****************************************************************************
  66. * Local variables
  67. ******************************************************************************/
  68. static METHODS Cone_Methods =
  69. {
  70. All_Cone_Intersections,
  71. Inside_Cone, Cone_Normal,
  72. (COPY_METHOD)Copy_Cone, Translate_Cone, Rotate_Cone, Scale_Cone, Transform_Cone,
  73. Invert_Cone, Destroy_Cone
  74. };
  75. /*****************************************************************************
  76. *
  77. * FUNCTION
  78. *
  79. * All_Cone_Intersections
  80. *
  81. * INPUT
  82. *
  83. * OUTPUT
  84. *
  85. * RETURNS
  86. *
  87. * AUTHOR
  88. *
  89. * Alexander Enzmann
  90. *
  91. * DESCRIPTION
  92. *
  93. * -
  94. *
  95. * CHANGES
  96. *
  97. * -
  98. *
  99. ******************************************************************************/
  100. static int All_Cone_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  101. {
  102. int Intersection_Found, cnt, i;
  103. VECTOR IPoint;
  104. CONE_INT I[4];
  105. Intersection_Found = FALSE;
  106. if ((cnt = intersect_cone(Ray, (CONE *)Object, I)) != 0)
  107. {
  108. for (i = 0; i < cnt; i++)
  109. {
  110. VEvaluateRay(IPoint, Ray->Initial, I[i].d, Ray->Direction);
  111. if (Point_In_Clip(IPoint, Object->Clip))
  112. {
  113. push_entry_i1(I[i].d,IPoint,Object,I[i].t,Depth_Stack);
  114. Intersection_Found = TRUE;
  115. }
  116. }
  117. }
  118. return (Intersection_Found);
  119. }
  120. /*****************************************************************************
  121. *
  122. * FUNCTION
  123. *
  124. * intersect_cone
  125. *
  126. * INPUT
  127. *
  128. * OUTPUT
  129. *
  130. * RETURNS
  131. *
  132. * AUTHOR
  133. *
  134. * Alexander Enzmann
  135. *
  136. * DESCRIPTION
  137. *
  138. * -
  139. *
  140. * CHANGES
  141. *
  142. * -
  143. *
  144. ******************************************************************************/
  145. static int intersect_cone(RAY *Ray, CONE *Cone, CONE_INT *Intersection)
  146. {
  147. int i = 0;
  148. DBL a, b, c, z, t1, t2, len;
  149. DBL d;
  150. VECTOR P, D;
  151. Increase_Counter(stats[Ray_Cone_Tests]);
  152. /* Transform the ray into the cones space */
  153. MInvTransPoint(P, Ray->Initial, Cone->Trans);
  154. MInvTransDirection(D, Ray->Direction, Cone->Trans);
  155. VLength(len, D);
  156. VInverseScaleEq(D, len);
  157. if (Test_Flag(Cone, CYLINDER_FLAG))
  158. {
  159. /* Solve intersections with a cylinder */
  160. a = D[X] * D[X] + D[Y] * D[Y];
  161. if (a > EPSILON)
  162. {
  163. b = P[X] * D[X] + P[Y] * D[Y];
  164. c = P[X] * P[X] + P[Y] * P[Y] - 1.0;
  165. d = b * b - a * c;
  166. if (d >= 0.0)
  167. {
  168. d = sqrt(d);
  169. t1 = (-b + d) / a;
  170. t2 = (-b - d) / a;
  171. z = P[Z] + t1 * D[Z];
  172. if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= 0.0) && (z <= 1.0))
  173. {
  174. Intersection[i].d = t1 / len;
  175. Intersection[i++].t = SIDE_HIT;
  176. }
  177. z = P[Z] + t2 * D[Z];
  178. if ((t2 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= 0.0) && (z <= 1.0))
  179. {
  180. Intersection[i].d = t2 / len;
  181. Intersection[i++].t = SIDE_HIT;
  182. }
  183. }
  184. }
  185. }
  186. else
  187. {
  188. /* Solve intersections with a cone */
  189. a = D[X] * D[X] + D[Y] * D[Y] - D[Z] * D[Z];
  190. b = D[X] * P[X] + D[Y] * P[Y] - D[Z] * P[Z];
  191. c = P[X] * P[X] + P[Y] * P[Y] - P[Z] * P[Z];
  192. if (fabs(a) < EPSILON)
  193. {
  194. if (fabs(b) > EPSILON)
  195. {
  196. /* One intersection */
  197. t1 = -0.5 * c / b;
  198. z = P[Z] + t1 * D[Z];
  199. if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
  200. {
  201. Intersection[i].d = t1 / len;
  202. Intersection[i++].t = SIDE_HIT;
  203. }
  204. }
  205. }
  206. else
  207. {
  208. /* Check hits against the side of the cone */
  209. d = b * b - a * c;
  210. if (d >= 0.0)
  211. {
  212. d = sqrt(d);
  213. t1 = (-b - d) / a;
  214. t2 = (-b + d) / a;
  215. z = P[Z] + t1 * D[Z];
  216. if ((t1 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
  217. {
  218. Intersection[i].d = t1 / len;
  219. Intersection[i++].t = SIDE_HIT;
  220. }
  221. z = P[Z] + t2 * D[Z];
  222. if ((t2 > Cone_Tolerance) && (t1 < Max_Distance) && (z >= Cone->dist) && (z <= 1.0))
  223. {
  224. Intersection[i].d = t2 / len;
  225. Intersection[i++].t = SIDE_HIT;
  226. }
  227. }
  228. }
  229. }
  230. if (Test_Flag(Cone, CLOSED_FLAG) && (fabs(D[Z]) > EPSILON))
  231. {
  232. d = (1.0 - P[Z]) / D[Z];
  233. a = (P[X] + d * D[X]);
  234. b = (P[Y] + d * D[Y]);
  235. if (((Sqr(a) + Sqr(b)) <= 1.0) && (d > Cone_Tolerance) && (d < Max_Distance))
  236. {
  237. Intersection[i].d = d / len;
  238. Intersection[i++].t = CAP_HIT;
  239. }
  240. d = (Cone->dist - P[Z]) / D[Z];
  241. a = (P[X] + d * D[X]);
  242. b = (P[Y] + d * D[Y]);
  243. if ((Sqr(a) + Sqr(b)) <= (Test_Flag(Cone, CYLINDER_FLAG) ? 1.0 : Sqr(Cone->dist))
  244. && (d > Cone_Tolerance) && (d < Max_Distance))
  245. {
  246. Intersection[i].d = d / len;
  247. Intersection[i++].t = BASE_HIT;
  248. }
  249. }
  250. if (i)
  251. {
  252. Increase_Counter(stats[Ray_Cone_Tests_Succeeded]);
  253. }
  254. return (i);
  255. }
  256. /*****************************************************************************
  257. *
  258. * FUNCTION
  259. *
  260. * Inside_Cone
  261. *
  262. * INPUT
  263. *
  264. * OUTPUT
  265. *
  266. * RETURNS
  267. *
  268. * AUTHOR
  269. *
  270. * Alexander Enzmann
  271. *
  272. * DESCRIPTION
  273. *
  274. * -
  275. *
  276. * CHANGES
  277. *
  278. * -
  279. *
  280. ******************************************************************************/
  281. static int Inside_Cone(VECTOR IPoint, OBJECT *Object)
  282. {
  283. CONE *Cone = (CONE *)Object;
  284. DBL w2, z2, offset = (Test_Flag(Cone, CLOSED_FLAG) ? -EPSILON : EPSILON);
  285. VECTOR New_Point;
  286. /* Transform the point into the cones space */
  287. MInvTransPoint(New_Point, IPoint, Cone->Trans);
  288. /* Test to see if we are inside the cone */
  289. w2 = New_Point[X] * New_Point[X] + New_Point[Y] * New_Point[Y];
  290. if (Test_Flag(Cone, CYLINDER_FLAG))
  291. {
  292. /* Check to see if we are inside a cylinder */
  293. if ((w2 > 1.0 + offset) ||
  294. (New_Point[Z] < 0.0 - offset) ||
  295. (New_Point[Z] > 1.0 + offset))
  296. {
  297. return (Test_Flag(Cone, INVERTED_FLAG));
  298. }
  299. else
  300. {
  301. return (!Test_Flag(Cone, INVERTED_FLAG));
  302. }
  303. }
  304. else
  305. {
  306. /* Check to see if we are inside a cone */
  307. z2 = New_Point[Z] * New_Point[Z];
  308. if ((w2 > z2 + offset) ||
  309. (New_Point[Z] < Cone->dist - offset) ||
  310. (New_Point[Z] > 1.0+offset))
  311. {
  312. return (Test_Flag(Cone, INVERTED_FLAG));
  313. }
  314. else
  315. {
  316. return (!Test_Flag(Cone, INVERTED_FLAG));
  317. }
  318. }
  319. }
  320. /*****************************************************************************
  321. *
  322. * FUNCTION
  323. *
  324. * Cone_Normal
  325. *
  326. * INPUT
  327. *
  328. * OUTPUT
  329. *
  330. * RETURNS
  331. *
  332. * AUTHOR
  333. *
  334. * Alexander Enzmann
  335. *
  336. * DESCRIPTION
  337. *
  338. * -
  339. *
  340. * CHANGES
  341. *
  342. * -
  343. *
  344. ******************************************************************************/
  345. static void Cone_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  346. {
  347. CONE *Cone = (CONE *)Object;
  348. /* Transform the point into the cones space */
  349. MInvTransPoint(Result, Inter->IPoint, Cone->Trans);
  350. /* Calculating the normal is real simple in canonical cone space */
  351. switch (Inter->i1)
  352. {
  353. case SIDE_HIT:
  354. if (Test_Flag(Cone, CYLINDER_FLAG))
  355. {
  356. Result[Z] = 0.0;
  357. }
  358. else
  359. {
  360. Result[Z] = -Result[Z];
  361. }
  362. break;
  363. case BASE_HIT:
  364. Make_Vector(Result, 0.0, 0.0, -1.0)
  365. break;
  366. case CAP_HIT:
  367. Make_Vector(Result, 0.0, 0.0, 1.0)
  368. break;
  369. }
  370. /* Transform the point out of the cones space */
  371. MTransNormal(Result, Result, Cone->Trans);
  372. VNormalize(Result, Result);
  373. }
  374. /*****************************************************************************
  375. *
  376. * FUNCTION
  377. *
  378. * Translate_Cone
  379. *
  380. * INPUT
  381. *
  382. * OUTPUT
  383. *
  384. * RETURNS
  385. *
  386. * AUTHOR
  387. *
  388. * Alexander Enzmann
  389. *
  390. * DESCRIPTION
  391. *
  392. * -
  393. *
  394. * CHANGES
  395. *
  396. * -
  397. *
  398. ******************************************************************************/
  399. static void Translate_Cone(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  400. {
  401. Transform_Cone(Object, Trans);
  402. }
  403. /*****************************************************************************
  404. *
  405. * FUNCTION
  406. *
  407. * Rotate_Cone
  408. *
  409. * INPUT
  410. *
  411. * OUTPUT
  412. *
  413. * RETURNS
  414. *
  415. * AUTHOR
  416. *
  417. * Alexander Enzmann
  418. *
  419. * DESCRIPTION
  420. *
  421. * -
  422. *
  423. * CHANGES
  424. *
  425. * -
  426. *
  427. ******************************************************************************/
  428. static void Rotate_Cone(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  429. {
  430. Transform_Cone(Object, Trans);
  431. }
  432. /*****************************************************************************
  433. *
  434. * FUNCTION
  435. *
  436. * Scale_Cone
  437. *
  438. * INPUT
  439. *
  440. * OUTPUT
  441. *
  442. * RETURNS
  443. *
  444. * AUTHOR
  445. *
  446. * Alexander Enzmann
  447. *
  448. * DESCRIPTION
  449. *
  450. * -
  451. *
  452. * CHANGES
  453. *
  454. * -
  455. *
  456. ******************************************************************************/
  457. static void Scale_Cone(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  458. {
  459. Transform_Cone(Object, Trans);
  460. }
  461. /*****************************************************************************
  462. *
  463. * FUNCTION
  464. *
  465. * Transform_Cone
  466. *
  467. * INPUT
  468. *
  469. * OUTPUT
  470. *
  471. * RETURNS
  472. *
  473. * AUTHOR
  474. *
  475. * Alexander Enzmann
  476. *
  477. * DESCRIPTION
  478. *
  479. * -
  480. *
  481. * CHANGES
  482. *
  483. * -
  484. *
  485. ******************************************************************************/
  486. static void Transform_Cone(OBJECT *Object, TRANSFORM *Trans)
  487. {
  488. CONE *Cone = (CONE *)Object;
  489. Compose_Transforms(Cone->Trans, Trans);
  490. Compute_Cone_BBox(Cone);
  491. }
  492. /*****************************************************************************
  493. *
  494. * FUNCTION
  495. *
  496. * Invert_Cone
  497. *
  498. * INPUT
  499. *
  500. * OUTPUT
  501. *
  502. * RETURNS
  503. *
  504. * AUTHOR
  505. *
  506. * Alexander Enzmann
  507. *
  508. * DESCRIPTION
  509. *
  510. * -
  511. *
  512. * CHANGES
  513. *
  514. * -
  515. *
  516. ******************************************************************************/
  517. static void Invert_Cone(OBJECT *Object)
  518. {
  519. Invert_Flag(Object, INVERTED_FLAG);
  520. }
  521. /*****************************************************************************
  522. *
  523. * FUNCTION
  524. *
  525. * Create_Cone
  526. *
  527. * INPUT
  528. *
  529. * OUTPUT
  530. *
  531. * RETURNS
  532. *
  533. * AUTHOR
  534. *
  535. * Alexander Enzmann
  536. *
  537. * DESCRIPTION
  538. *
  539. * -
  540. *
  541. * CHANGES
  542. *
  543. * -
  544. *
  545. ******************************************************************************/
  546. CONE *Create_Cone()
  547. {
  548. CONE *New;
  549. New = (CONE *)POV_MALLOC(sizeof(CONE), "cone");
  550. INIT_OBJECT_FIELDS(New, CONE_OBJECT, &Cone_Methods)
  551. Make_Vector(New->apex, 0.0, 0.0, 1.0);
  552. Make_Vector(New->base, 0.0, 0.0, 0.0);
  553. New->apex_radius = 1.0;
  554. New->base_radius = 0.0;
  555. New->dist = 0.0;
  556. New->Trans = Create_Transform();
  557. /* Cone/Cylinder has capped ends by default. */
  558. Set_Flag(New, CLOSED_FLAG);
  559. /* Default bounds */
  560. Make_BBox(New->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
  561. return (New);
  562. }
  563. /*****************************************************************************
  564. *
  565. * FUNCTION
  566. *
  567. * Copy_Cone
  568. *
  569. * INPUT
  570. *
  571. * OUTPUT
  572. *
  573. * RETURNS
  574. *
  575. * AUTHOR
  576. *
  577. * Alexander Enzmann
  578. *
  579. * DESCRIPTION
  580. *
  581. * -
  582. *
  583. * CHANGES
  584. *
  585. * -
  586. *
  587. ******************************************************************************/
  588. static CONE *Copy_Cone(OBJECT *Object)
  589. {
  590. CONE *New;
  591. New = Create_Cone();
  592. /* Get rid of the transformation created in Create_Cone(). */
  593. Destroy_Transform(New->Trans);
  594. /* Copy cone. */
  595. *New = *((CONE *)Object);
  596. New->Trans = Copy_Transform(((CONE *)Object)->Trans);
  597. return (New);
  598. }
  599. /*****************************************************************************
  600. *
  601. * FUNCTION
  602. *
  603. * Create_Cylinder
  604. *
  605. * INPUT
  606. *
  607. * OUTPUT
  608. *
  609. * RETURNS
  610. *
  611. * AUTHOR
  612. *
  613. * Alexander Enzmann
  614. *
  615. * DESCRIPTION
  616. *
  617. * -
  618. *
  619. * CHANGES
  620. *
  621. * -
  622. *
  623. ******************************************************************************/
  624. CONE *Create_Cylinder()
  625. {
  626. CONE *New;
  627. New = (CONE *)POV_MALLOC(sizeof(CONE), "cone");
  628. INIT_OBJECT_FIELDS(New, CONE_OBJECT, &Cone_Methods)
  629. Make_Vector(New->apex, 0.0, 0.0, 1.0);
  630. Make_Vector(New->base, 0.0, 0.0, 0.0);
  631. New->apex_radius = 1.0;
  632. New->base_radius = 1.0;
  633. New->dist = 0.0;
  634. New->Trans = Create_Transform();
  635. Set_Flag(New, CYLINDER_FLAG); /* This is a cylinder. */
  636. Set_Flag(New, CLOSED_FLAG); /* Has capped ends. */
  637. /* Default bounds */
  638. Make_BBox(New->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
  639. return (New);
  640. }
  641. /*****************************************************************************
  642. *
  643. * FUNCTION
  644. *
  645. * Compute_Cone_Data
  646. *
  647. * INPUT
  648. *
  649. * OUTPUT
  650. *
  651. * RETURNS
  652. *
  653. * AUTHOR
  654. *
  655. * Alexander Enzmann
  656. *
  657. * DESCRIPTION
  658. *
  659. * -
  660. *
  661. * CHANGES
  662. *
  663. * Feb 1996: check for equal sized ends (cylinder) first [AED]
  664. *
  665. ******************************************************************************/
  666. void Compute_Cone_Data(OBJECT *Object)
  667. {
  668. DBL tlen, len, tmpf;
  669. VECTOR tmpv, axis, origin;
  670. CONE *Cone = (CONE *)Object;
  671. /* Process the primitive specific information */
  672. if (fabs(Cone->apex_radius - Cone->base_radius) < EPSILON)
  673. {
  674. /* What we are dealing with here is really a cylinder */
  675. Set_Flag(Cone, CYLINDER_FLAG);
  676. Compute_Cylinder_Data(Object);
  677. return;
  678. }
  679. if (Cone->apex_radius < Cone->base_radius)
  680. {
  681. /* Want the bigger end at the top */
  682. Assign_Vector(tmpv,Cone->base);
  683. Assign_Vector(Cone->base,Cone->apex);
  684. Assign_Vector(Cone->apex,tmpv);
  685. tmpf = Cone->base_radius;
  686. Cone->base_radius = Cone->apex_radius;
  687. Cone->apex_radius = tmpf;
  688. }
  689. /* Find the axis and axis length */
  690. VSub(axis, Cone->apex, Cone->base);
  691. VLength(len, axis);
  692. if (len < EPSILON)
  693. {
  694. Error("Degenerate cone/cylinder.\n");
  695. }
  696. else
  697. {
  698. VInverseScaleEq(axis, len)
  699. }
  700. /* Determine alignment */
  701. tmpf = Cone->base_radius * len / (Cone->apex_radius - Cone->base_radius);
  702. VScale(origin, axis, tmpf);
  703. VSub(origin, Cone->base, origin);
  704. tlen = tmpf + len;
  705. Cone->dist = tmpf / tlen;
  706. Compute_Coordinate_Transform(Cone->Trans, origin, axis, Cone->apex_radius, tlen);
  707. /* Recalculate the bounds */
  708. Compute_Cone_BBox(Cone);
  709. }
  710. /*****************************************************************************
  711. *
  712. * FUNCTION
  713. *
  714. * Compute_Cylinder_Data
  715. *
  716. * INPUT
  717. *
  718. * OUTPUT
  719. *
  720. * RETURNS
  721. *
  722. * AUTHOR
  723. *
  724. * Alexander Enzmann
  725. *
  726. * DESCRIPTION
  727. *
  728. * -
  729. *
  730. * CHANGES
  731. *
  732. * -
  733. *
  734. ******************************************************************************/
  735. void Compute_Cylinder_Data(OBJECT *Object)
  736. {
  737. DBL tmpf;
  738. VECTOR axis;
  739. CONE *Cone = (CONE *)Object;
  740. VSub(axis, Cone->apex, Cone->base);
  741. VLength(tmpf, axis);
  742. if (tmpf < EPSILON)
  743. {
  744. Error("Degenerate cylinder, base point = apex point.\n");
  745. }
  746. else
  747. {
  748. VInverseScaleEq(axis, tmpf)
  749. Compute_Coordinate_Transform(Cone->Trans, Cone->base, axis, Cone->apex_radius, tmpf);
  750. }
  751. Cone->dist = 0.0;
  752. /* Recalculate the bounds */
  753. Compute_Cone_BBox(Cone);
  754. }
  755. /*****************************************************************************
  756. *
  757. * FUNCTION
  758. *
  759. * Destroy_Cone
  760. *
  761. * INPUT
  762. *
  763. * OUTPUT
  764. *
  765. * RETURNS
  766. *
  767. * AUTHOR
  768. *
  769. * Alexander Enzmann
  770. *
  771. * DESCRIPTION
  772. *
  773. * -
  774. *
  775. * CHANGES
  776. *
  777. * -
  778. *
  779. ******************************************************************************/
  780. static void Destroy_Cone(OBJECT *Object)
  781. {
  782. Destroy_Transform(((CONE *)Object)->Trans);
  783. POV_FREE (Object);
  784. }
  785. /*****************************************************************************
  786. *
  787. * FUNCTION
  788. *
  789. * Compute_Cone_BBox
  790. *
  791. * INPUT
  792. *
  793. * Cone - Cone/Cylinder
  794. *
  795. * OUTPUT
  796. *
  797. * Cone
  798. *
  799. * RETURNS
  800. *
  801. * AUTHOR
  802. *
  803. * Dieter Bayer
  804. *
  805. * DESCRIPTION
  806. *
  807. * Calculate the bounding box of a cone or cylinder.
  808. *
  809. * CHANGES
  810. *
  811. * Aug 1994 : Creation.
  812. *
  813. ******************************************************************************/
  814. void Compute_Cone_BBox(CONE *Cone)
  815. {
  816. Make_BBox(Cone->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0);
  817. Recompute_BBox(&Cone->BBox, Cone->Trans);
  818. }