TORUS.C 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. /****************************************************************************
  2. * torus.c
  3. *
  4. * This module implements functions that manipulate torii.
  5. *
  6. * This module was written by Dieter Bayer [DB].
  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. /****************************************************************************
  26. *
  27. * Explanation:
  28. *
  29. * ---
  30. *
  31. * June 1994 : Creation. [DB]
  32. *
  33. *****************************************************************************/
  34. #include "frame.h"
  35. #include "povray.h"
  36. #include "vector.h"
  37. #include "povproto.h"
  38. #include "bbox.h"
  39. #include "polysolv.h"
  40. #include "matrices.h"
  41. #include "objects.h"
  42. #include "torus.h"
  43. /*****************************************************************************
  44. * Local preprocessor defines
  45. ******************************************************************************/
  46. /* Minimal depth for a valid intersection. */
  47. #define DEPTH_TOLERANCE 1.0e-4
  48. /* Tolerance used for order reduction during root finding. */
  49. #define ROOT_TOLERANCE 1.0e-4
  50. /*****************************************************************************
  51. * Static functions
  52. ******************************************************************************/
  53. static int intersect_torus (RAY *Ray, TORUS *Torus, DBL *Depth);
  54. static int All_Torus_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  55. static int Inside_Torus (VECTOR point, OBJECT *Object);
  56. static void Torus_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  57. static TORUS *Copy_Torus (OBJECT *Object);
  58. static void Translate_Torus (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  59. static void Rotate_Torus (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  60. static void Scale_Torus (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  61. static void Transform_Torus (OBJECT *Object, TRANSFORM *Trans);
  62. static void Invert_Torus (OBJECT *Object);
  63. static void Destroy_Torus (OBJECT *Object);
  64. /*****************************************************************************
  65. * Local variables
  66. ******************************************************************************/
  67. static METHODS Torus_Methods =
  68. {
  69. All_Torus_Intersections, Inside_Torus, Torus_Normal,
  70. (COPY_METHOD)Copy_Torus, Translate_Torus, Rotate_Torus,
  71. Scale_Torus, Transform_Torus, Invert_Torus, Destroy_Torus
  72. };
  73. /*****************************************************************************
  74. *
  75. * FUNCTION
  76. *
  77. * All_Torus_Intersections
  78. *
  79. * INPUT
  80. *
  81. * Object - Object
  82. * Ray - Ray
  83. * Depth_Stack - Intersection stack
  84. *
  85. * OUTPUT
  86. *
  87. * Depth_Stack
  88. *
  89. * RETURNS
  90. *
  91. * int - TRUE, if an intersection was found
  92. *
  93. * AUTHOR
  94. *
  95. * Dieter Bayer
  96. *
  97. * DESCRIPTION
  98. *
  99. * Determine ray/torus intersection and clip intersection found.
  100. *
  101. * CHANGES
  102. *
  103. * Jun 1994 : Creation.
  104. *
  105. ******************************************************************************/
  106. static int All_Torus_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  107. {
  108. int i, max_i, Found;
  109. DBL Depth[4];
  110. VECTOR IPoint;
  111. Found = FALSE;
  112. if ((max_i = intersect_torus(Ray, (TORUS *)Object, Depth)) > 0)
  113. {
  114. for (i = 0; i < max_i; i++)
  115. {
  116. if ((Depth[i] > DEPTH_TOLERANCE) && (Depth[i] < Max_Distance))
  117. {
  118. VEvaluateRay(IPoint, Ray->Initial, Depth[i], Ray->Direction);
  119. if (Point_In_Clip(IPoint, Object->Clip))
  120. {
  121. push_entry(Depth[i], IPoint, Object, Depth_Stack);
  122. Found = TRUE;
  123. }
  124. }
  125. }
  126. }
  127. return(Found);
  128. }
  129. /*****************************************************************************
  130. *
  131. * FUNCTION
  132. *
  133. * intersect_torus
  134. *
  135. * INPUT
  136. *
  137. * Ray - Ray
  138. * Torus - Torus
  139. * Depth - Intersections found
  140. *
  141. * OUTPUT
  142. *
  143. * Depth
  144. *
  145. * RETURNS
  146. *
  147. * int - Number of intersections found
  148. *
  149. * AUTHOR
  150. *
  151. * Dieter Bayer
  152. *
  153. * DESCRIPTION
  154. *
  155. * Determine ray/torus intersection.
  156. *
  157. * Note that the torus is rotated about the y-axis!
  158. *
  159. * CHANGES
  160. *
  161. * Jun 1994 : Creation.
  162. *
  163. ******************************************************************************/
  164. static int intersect_torus(RAY *Ray, TORUS *Torus, DBL *Depth)
  165. {
  166. int i, n;
  167. DBL len, R2, Py2, Dy2, PDy2, k1, k2;
  168. DBL y1, y2, r1, r2;
  169. DBL c[5], r[4];
  170. VECTOR P, D;
  171. Increase_Counter(stats[Ray_Torus_Tests]);
  172. /* Transform the ray into the torus space. */
  173. MInvTransPoint(P, Ray->Initial, Torus->Trans);
  174. MInvTransDirection(D, Ray->Direction, Torus->Trans);
  175. VLength(len, D);
  176. VInverseScaleEq(D, len);
  177. i = 0;
  178. y1 = -Torus->r;
  179. y2 = Torus->r;
  180. r1 = Sqr(Torus->R - Torus->r);
  181. r2 = Sqr(Torus->R + Torus->r);
  182. #ifdef TORUS_EXTRA_STATS
  183. Increase_Counter(stats[Torus_Bound_Tests]);
  184. #endif
  185. if (Test_Thick_Cylinder(P, D, y1, y2, r1, r2))
  186. {
  187. #ifdef TORUS_EXTRA_STATS
  188. Increase_Counter(stats[Torus_Bound_Tests_Succeeded]);
  189. #endif
  190. R2 = Sqr(Torus->R);
  191. r2 = Sqr(Torus->r);
  192. Py2 = P[Y] * P[Y];
  193. Dy2 = D[Y] * D[Y];
  194. PDy2 = P[Y] * D[Y];
  195. k1 = P[X] * P[X] + P[Z] * P[Z] + Py2 - R2 - r2;
  196. k2 = P[X] * D[X] + P[Z] * D[Z] + PDy2;
  197. c[0] = 1.0;
  198. c[1] = 4.0 * k2;
  199. c[2] = 2.0 * (k1 + 2.0 * (k2 * k2 + R2 * Dy2));
  200. c[3] = 4.0 * (k2 * k1 + 2.0 * R2 * PDy2);
  201. c[4] = k1 * k1 + 4.0 * R2 * (Py2 - r2);
  202. n = Solve_Polynomial(4, c, r, Test_Flag(Torus, STURM_FLAG), ROOT_TOLERANCE);
  203. while(n--)
  204. {
  205. Depth[i++] = r[n] / len;
  206. }
  207. }
  208. if (i)
  209. {
  210. Increase_Counter(stats[Ray_Torus_Tests_Succeeded]);
  211. }
  212. return(i);
  213. }
  214. /*****************************************************************************
  215. *
  216. * FUNCTION
  217. *
  218. * Inside_Torus
  219. *
  220. * INPUT
  221. *
  222. * IPoint - Intersection point
  223. * Object - Object
  224. *
  225. * OUTPUT
  226. *
  227. * RETURNS
  228. *
  229. * int - TRUE if inside
  230. *
  231. * AUTHOR
  232. *
  233. * Dieter Bayer
  234. *
  235. * DESCRIPTION
  236. *
  237. * Test if a point lies inside the torus.
  238. *
  239. * CHANGES
  240. *
  241. * Jun 1994 : Creation.
  242. *
  243. ******************************************************************************/
  244. static int Inside_Torus(VECTOR IPoint, OBJECT *Object)
  245. {
  246. DBL r, r2;
  247. VECTOR P;
  248. TORUS *Torus = (TORUS *)Object;
  249. /* Transform the point into the torus space. */
  250. MInvTransPoint(P, IPoint, Torus->Trans);
  251. r = sqrt(Sqr(P[X]) + Sqr(P[Z]));
  252. r2 = Sqr(P[Y]) + Sqr(r - Torus->R);
  253. if (r2 <= Sqr(Torus->r))
  254. {
  255. return(!Test_Flag(Torus, INVERTED_FLAG));
  256. }
  257. else
  258. {
  259. return(Test_Flag(Torus, INVERTED_FLAG));
  260. }
  261. }
  262. /*****************************************************************************
  263. *
  264. * FUNCTION
  265. *
  266. * Torus_Normal
  267. *
  268. * INPUT
  269. *
  270. * Result - Normal vector
  271. * Object - Object
  272. * Inter - Intersection found
  273. *
  274. * OUTPUT
  275. *
  276. * Result
  277. *
  278. * RETURNS
  279. *
  280. * AUTHOR
  281. *
  282. * Dieter Bayer
  283. *
  284. * DESCRIPTION
  285. *
  286. * Calculate the normal of the torus in a given point.
  287. *
  288. * CHANGES
  289. *
  290. * Jun 1994 : Creation.
  291. *
  292. ******************************************************************************/
  293. static void Torus_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  294. {
  295. DBL dist;
  296. VECTOR P, N, M;
  297. TORUS *Torus = (TORUS *)Object;
  298. /* Transform the point into the torus space. */
  299. MInvTransPoint(P, Inter->IPoint, Torus->Trans);
  300. /* Get normal from derivatives. */
  301. dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);
  302. if (dist > EPSILON)
  303. {
  304. M[X] = Torus->R * P[X] / dist;
  305. M[Y] = 0.0;
  306. M[Z] = Torus->R * P[Z] / dist;
  307. }
  308. else
  309. {
  310. Make_Vector(M, 0.0, 0.0, 0.0);
  311. }
  312. VSub(N, P, M);
  313. /* Transform the normalt out of the torus space. */
  314. MTransNormal(Result, N, Torus->Trans);
  315. VNormalize(Result, Result);
  316. }
  317. /*****************************************************************************
  318. *
  319. * FUNCTION
  320. *
  321. * Translate_Torus
  322. *
  323. * INPUT
  324. *
  325. * Object - Object
  326. * Vector - Translation vector
  327. *
  328. * OUTPUT
  329. *
  330. * Object
  331. *
  332. * RETURNS
  333. *
  334. * AUTHOR
  335. *
  336. * Dieter Bayer
  337. *
  338. * DESCRIPTION
  339. *
  340. * Translate a torus.
  341. *
  342. * CHANGES
  343. *
  344. * Jun 1994 : Creation.
  345. *
  346. ******************************************************************************/
  347. static void Translate_Torus(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  348. {
  349. Transform_Torus(Object, Trans);
  350. }
  351. /*****************************************************************************
  352. *
  353. * FUNCTION
  354. *
  355. * Rotate_Torus
  356. *
  357. * INPUT
  358. *
  359. * Object - Object
  360. * Vector - Rotation vector
  361. *
  362. * OUTPUT
  363. *
  364. * Object
  365. *
  366. * RETURNS
  367. *
  368. * AUTHOR
  369. *
  370. * Dieter Bayer
  371. *
  372. * DESCRIPTION
  373. *
  374. * Rotate a torus.
  375. *
  376. * CHANGES
  377. *
  378. * Jun 1994 : Creation.
  379. *
  380. ******************************************************************************/
  381. static void Rotate_Torus(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  382. {
  383. Transform_Torus(Object, Trans);
  384. }
  385. /*****************************************************************************
  386. *
  387. * FUNCTION
  388. *
  389. * Scale_Torus
  390. *
  391. * INPUT
  392. *
  393. * Object - Object
  394. * Vector - Scaling vector
  395. *
  396. * OUTPUT
  397. *
  398. * Object
  399. *
  400. * RETURNS
  401. *
  402. * AUTHOR
  403. *
  404. * Dieter Bayer
  405. *
  406. * DESCRIPTION
  407. *
  408. * Scale a torus.
  409. *
  410. * CHANGES
  411. *
  412. * Jun 1994 : Creation.
  413. *
  414. ******************************************************************************/
  415. static void Scale_Torus(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  416. {
  417. Transform_Torus(Object, Trans);
  418. }
  419. /*****************************************************************************
  420. *
  421. * FUNCTION
  422. *
  423. * Transform_Torus
  424. *
  425. * INPUT
  426. *
  427. * Object - Object
  428. * Trans - Transformation to apply
  429. *
  430. * OUTPUT
  431. *
  432. * Object
  433. *
  434. * RETURNS
  435. *
  436. * AUTHOR
  437. *
  438. * Dieter Bayer
  439. *
  440. * DESCRIPTION
  441. *
  442. * Transform a torus and recalculate its bounding box.
  443. *
  444. * CHANGES
  445. *
  446. * Jun 1994 : Creation.
  447. *
  448. ******************************************************************************/
  449. static void Transform_Torus(OBJECT *Object, TRANSFORM *Trans)
  450. {
  451. Compose_Transforms(((TORUS *)Object)->Trans, Trans);
  452. Compute_Torus_BBox((TORUS *)Object);
  453. }
  454. /*****************************************************************************
  455. *
  456. * FUNCTION
  457. *
  458. * Invert_Torus
  459. *
  460. * INPUT
  461. *
  462. * Object - Object
  463. *
  464. * OUTPUT
  465. *
  466. * Object
  467. *
  468. * RETURNS
  469. *
  470. * AUTHOR
  471. *
  472. * Dieter Bayer
  473. *
  474. * DESCRIPTION
  475. *
  476. * Invert a torus.
  477. *
  478. * CHANGES
  479. *
  480. * Jun 1994 : Creation.
  481. *
  482. ******************************************************************************/
  483. static void Invert_Torus(OBJECT *Object)
  484. {
  485. Invert_Flag(Object, INVERTED_FLAG);
  486. }
  487. /*****************************************************************************
  488. *
  489. * FUNCTION
  490. *
  491. * Create_Torus
  492. *
  493. * INPUT
  494. *
  495. * OUTPUT
  496. *
  497. * RETURNS
  498. *
  499. * TORUS * - new torus
  500. *
  501. * AUTHOR
  502. *
  503. * Dieter Bayer
  504. *
  505. * DESCRIPTION
  506. *
  507. * Create a new torus.
  508. *
  509. * CHANGES
  510. *
  511. * Jun 1994 : Creation.
  512. *
  513. ******************************************************************************/
  514. TORUS *Create_Torus()
  515. {
  516. TORUS *New;
  517. New = (TORUS *)POV_MALLOC(sizeof(TORUS), "torus");
  518. INIT_OBJECT_FIELDS(New,TORUS_OBJECT,&Torus_Methods)
  519. New->Trans = Create_Transform();
  520. New->R =
  521. New->r = 0.0;
  522. return (New);
  523. }
  524. /*****************************************************************************
  525. *
  526. * FUNCTION
  527. *
  528. * Copy_Torus
  529. *
  530. * INPUT
  531. *
  532. * Object - Object
  533. *
  534. * OUTPUT
  535. *
  536. * RETURNS
  537. *
  538. * void * - New torus
  539. *
  540. * AUTHOR
  541. *
  542. * Dieter Bayer
  543. *
  544. * DESCRIPTION
  545. *
  546. * Copy a torus.
  547. *
  548. * CHANGES
  549. *
  550. * Jun 1994 : Creation.
  551. *
  552. * Sep 1994 : fixed memory leakage [DB]
  553. *
  554. ******************************************************************************/
  555. static TORUS *Copy_Torus(OBJECT *Object)
  556. {
  557. TORUS *New, *Torus = (TORUS *)Object;
  558. New = Create_Torus();
  559. /* Get rid of the transformation created in Create_Torus(). */
  560. Destroy_Transform(New->Trans);
  561. /* Copy torus. */
  562. *New = *Torus;
  563. New->Trans = Copy_Transform(Torus->Trans);
  564. return (New);
  565. }
  566. /*****************************************************************************
  567. *
  568. * FUNCTION
  569. *
  570. * Destroy_Torus
  571. *
  572. * INPUT
  573. *
  574. * Object - Object
  575. *
  576. * OUTPUT
  577. *
  578. * Object
  579. *
  580. * RETURNS
  581. *
  582. * AUTHOR
  583. *
  584. * Dieter Bayer
  585. *
  586. * DESCRIPTION
  587. *
  588. * Destroy a torus.
  589. *
  590. * CHANGES
  591. *
  592. * Jun 1994 : Creation.
  593. *
  594. ******************************************************************************/
  595. static void Destroy_Torus (OBJECT *Object)
  596. {
  597. Destroy_Transform(((TORUS *)Object)->Trans);
  598. POV_FREE (Object);
  599. }
  600. /*****************************************************************************
  601. *
  602. * FUNCTION
  603. *
  604. * Compute_Torus_BBox
  605. *
  606. * INPUT
  607. *
  608. * Torus - Torus
  609. *
  610. * OUTPUT
  611. *
  612. * Torus
  613. *
  614. * RETURNS
  615. *
  616. * AUTHOR
  617. *
  618. * Dieter Bayer
  619. *
  620. * DESCRIPTION
  621. *
  622. * Calculate the bounding box of a torus.
  623. *
  624. * CHANGES
  625. *
  626. * Jun 1994 : Creation.
  627. *
  628. ******************************************************************************/
  629. void Compute_Torus_BBox(TORUS *Torus)
  630. {
  631. DBL r1, r2;
  632. r1 = Torus->r;
  633. r2 = Torus->R + Torus->r;
  634. Make_BBox(Torus->BBox, -r2, -r1, -r2, 2.0 * r2, 2.0 * r1, 2.0 * r2);
  635. Recompute_BBox(&Torus->BBox, Torus->Trans);
  636. }
  637. /*****************************************************************************
  638. *
  639. * FUNCTION
  640. *
  641. * Test_Thick_Cylinder
  642. *
  643. * INPUT
  644. *
  645. * P - Ray initial
  646. * D - Ray direction
  647. * h1 - Height 1
  648. * h2 - Height 2
  649. * r1 - Square of inner radius
  650. * r2 - Square of outer radius
  651. *
  652. * OUTPUT
  653. *
  654. * RETURNS
  655. *
  656. * int - TRUE, if hit
  657. *
  658. * AUTHOR
  659. *
  660. * Dieter Bayer
  661. *
  662. * DESCRIPTION
  663. *
  664. * Test if a given ray defined in the lathe's coordinate system
  665. * intersects a "thick" cylinder (rotated about y-axis).
  666. *
  667. * CHANGES
  668. *
  669. * Jun 1994 : Creation.
  670. *
  671. ******************************************************************************/
  672. int Test_Thick_Cylinder(VECTOR P, VECTOR D, DBL h1, DBL h2, DBL r1, DBL r2)
  673. {
  674. DBL a, b, c, d;
  675. DBL u, v, k, r, h;
  676. if (fabs(D[Y]) < EPSILON)
  677. {
  678. if ((P[Y] < h1) || (P[Y] > h2))
  679. {
  680. return(FALSE);
  681. }
  682. }
  683. else
  684. {
  685. /* Intersect ray with the cap-plane. */
  686. k = (h2 - P[Y]) / D[Y];
  687. u = P[X] + k * D[X];
  688. v = P[Z] + k * D[Z];
  689. if ((k > EPSILON) && (k < Max_Distance))
  690. {
  691. r = u * u + v * v;
  692. if ((r >= r1) && (r <= r2))
  693. {
  694. return(TRUE);
  695. }
  696. }
  697. /* Intersectionersect ray with the base-plane. */
  698. k = (h1 - P[Y]) / D[Y];
  699. u = P[X] + k * D[X];
  700. v = P[Z] + k * D[Z];
  701. if ((k > EPSILON) && (k < Max_Distance))
  702. {
  703. r = u * u + v * v;
  704. if ((r >= r1) && (r <= r2))
  705. {
  706. return(TRUE);
  707. }
  708. }
  709. }
  710. a = D[X] * D[X] + D[Z] * D[Z];
  711. if (a > EPSILON)
  712. {
  713. /* Intersect with outer cylinder. */
  714. b = P[X] * D[X] + P[Z] * D[Z];
  715. c = P[X] * P[X] + P[Z] * P[Z] - r2;
  716. d = b * b - a * c;
  717. if (d >= 0.0)
  718. {
  719. d = sqrt(d);
  720. k = (-b + d) / a;
  721. if ((k > EPSILON) && (k < Max_Distance))
  722. {
  723. h = P[Y] + k * D[Y];
  724. if ((h >= h1) && (h <= h2))
  725. {
  726. return(TRUE);
  727. }
  728. }
  729. k = (-b - d) / a;
  730. if ((k > EPSILON) && (k < Max_Distance))
  731. {
  732. h = P[Y] + k * D[Y];
  733. if ((h >= h1) && (h <= h2))
  734. {
  735. return(TRUE);
  736. }
  737. }
  738. }
  739. /* Intersect with inner cylinder. */
  740. c = P[X] * P[X] + P[Z] * P[Z] - r1;
  741. d = b * b - a * c;
  742. if (d >= 0.0)
  743. {
  744. d = sqrt(d);
  745. k = (-b + d) / a;
  746. if ((k > EPSILON) && (k < Max_Distance))
  747. {
  748. h = P[Y] + k * D[Y];
  749. if ((h >= h1) && (h <= h2))
  750. {
  751. return(TRUE);
  752. }
  753. }
  754. k = (-b - d) / a;
  755. if ((k > EPSILON) && (k < Max_Distance))
  756. {
  757. h = P[Y] + k * D[Y];
  758. if ((h >= h1) && (h <= h2))
  759. {
  760. return(TRUE);
  761. }
  762. }
  763. }
  764. }
  765. return(FALSE);
  766. }