1 /****************************************************************************
4 * This module implements functions that manipulate superellipsoids.
6 * Original code written by Alexander Enzmann.
7 * Adaption to POV-Ray by Dieter Bayer [DB].
9 * from Persistence of Vision(tm) Ray Tracer
10 * Copyright 1996,1999 Persistence of Vision Team
11 *---------------------------------------------------------------------------
12 * NOTICE: This source code file is provided so that users may experiment
13 * with enhancements to POV-Ray and to port the software to platforms other
14 * than those supported by the POV-Ray Team. There are strict rules under
15 * which you are permitted to use this file. The rules are in the file
16 * named POVLEGAL.DOC which should be distributed with this file.
17 * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
18 * Team Coordinator by email to team-coord@povray.org or visit us on the web at
19 * http://www.povray.org. The latest version of POV-Ray may be found at this site.
21 * This program is based on the popular DKB raytracer version 2.12.
22 * DKBTrace was originally written by David K. Buck.
23 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
25 *****************************************************************************/
27 /****************************************************************************
31 * Superellipsoids are defined by the implicit equation
33 * f(x,y,z) = (|x|^(2/e) + |y|^(2/e))^(e/n) + |z|^(2/n) - 1
35 * Where e is the east/west exponent and n is the north/south exponent.
37 * NOTE: The exponents are precomputed and stored in the Power element.
39 * NOTE: Values of e and n that are close to degenerate (e.g.,
40 * below around 0.1) appear to give the root solver fits.
41 * Not sure quite where the problem lays just yet.
45 * superellipsoid { <e, n> }
50 * Oct 1994 : Creation.
52 *****************************************************************************/
65 /*****************************************************************************
66 * Local preprocessor defines
67 ******************************************************************************/
69 /* Minimal intersection depth for a valid intersection. */
71 #define DEPTH_TOLERANCE 1.0e-4
73 /* If |x| < ZERO_TOLERANCE it is regarded to be 0. */
75 #define ZERO_TOLERANCE 1.0e-10
77 /* This is not the signum function because SGNX(0) is 1. */
79 #define SGNX(x) (((x) >= 0.0) ? 1.0 : -1.0)
81 #define MIN_VALUE -1.0
84 #define MAX_ITERATIONS 20
90 /*****************************************************************************
92 ******************************************************************************/
96 /*****************************************************************************
98 ******************************************************************************/
100 static int intersect_superellipsoid (RAY
*Ray
, SUPERELLIPSOID
*Superellipsoid
, ISTACK
*Depth_Stack
);
101 static int intersect_box (VECTOR P
, VECTOR D
, DBL
*dmin
, DBL
*dmax
);
102 static DBL
power (DBL x
, DBL e
);
103 static DBL
evaluate_superellipsoid (VECTOR P
, SUPERELLIPSOID
*Superellipsoid
);
104 static int compdists (CONST
void *in_a
, CONST
void *in_b
);
106 static int find_ray_plane_points (VECTOR P
, VECTOR D
, int cnt
, DBL
*dists
, DBL mindist
, DBL maxdist
);
107 static void solve_hit1 (SUPERELLIPSOID
*Super
, DBL v0
, VECTOR tP0
, DBL v1
, VECTOR tP1
, VECTOR P
);
108 static int check_hit2 (SUPERELLIPSOID
*Super
, VECTOR P
, VECTOR D
, DBL t0
, VECTOR P0
, DBL v0
, DBL t1
, DBL
*t
, VECTOR Q
);
109 static int insert_hit (OBJECT
*Object
, RAY
*Ray
, DBL Depth
, ISTACK
*Depth_Stack
);
111 static int All_Superellipsoid_Intersections (OBJECT
*Object
, RAY
*Ray
, ISTACK
*Depth_Stack
);
112 static int Inside_Superellipsoid (VECTOR point
, OBJECT
*Object
);
113 static void Superellipsoid_Normal (VECTOR Result
, OBJECT
*Object
, INTERSECTION
*Inter
);
114 static SUPERELLIPSOID
*Copy_Superellipsoid (OBJECT
*Object
);
115 static void Translate_Superellipsoid (OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
);
116 static void Rotate_Superellipsoid (OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
);
117 static void Scale_Superellipsoid (OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
);
118 static void Transform_Superellipsoid (OBJECT
*Object
, TRANSFORM
*Trans
);
119 static void Invert_Superellipsoid (OBJECT
*Object
);
120 static void Destroy_Superellipsoid (OBJECT
*Object
);
122 /*****************************************************************************
124 ******************************************************************************/
126 static METHODS Superellipsoid_Methods
=
128 All_Superellipsoid_Intersections
,
129 Inside_Superellipsoid
, Superellipsoid_Normal
,
130 (COPY_METHOD
)Copy_Superellipsoid
,
131 Translate_Superellipsoid
, Rotate_Superellipsoid
,
132 Scale_Superellipsoid
, Transform_Superellipsoid
, Invert_Superellipsoid
, Destroy_Superellipsoid
135 static DBL planes
[PLANECOUNT
][4] =
136 {{1, 1, 0, 0}, {1,-1, 0, 0},
137 {1, 0, 1, 0}, {1, 0,-1, 0},
138 {0, 1, 1, 0}, {0, 1,-1, 0},
145 /*****************************************************************************
149 * All_Superellipsoid_Intersections
155 * Depth_Stack - Intersection stack
163 * int - TRUE, if a intersection was found
171 * Determine ray/superellipsoid intersection and clip intersection found.
175 * Oct 1994 : Creation.
177 ******************************************************************************/
179 static int All_Superellipsoid_Intersections(OBJECT
*Object
, RAY
*Ray
, ISTACK
*Depth_Stack
)
181 Increase_Counter(stats
[Ray_Superellipsoid_Tests
]);
183 if (intersect_superellipsoid(Ray
, (SUPERELLIPSOID
*)Object
, Depth_Stack
))
185 Increase_Counter(stats
[Ray_Superellipsoid_Tests_Succeeded
]);
197 /*****************************************************************************
201 * intersect_superellipsoid
206 * Superellipsoid - Superellipsoid
207 * Depth_Stack - Depth stack
215 * int - TRUE if intersections were found.
219 * Alexander Enzmann, Dieter Bayer
223 * Determine ray/superellipsoid intersection.
227 * Oct 1994 : Creation.
229 ******************************************************************************/
231 static int intersect_superellipsoid(RAY
*Ray
, SUPERELLIPSOID
*Superellipsoid
, ISTACK
*Depth_Stack
)
233 int i
, cnt
, Found
= FALSE
;
234 DBL dists
[PLANECOUNT
+2];
235 DBL t
, t1
, t2
, v0
, v1
, len
;
236 VECTOR P
, D
, P0
, P1
, P2
, P3
;
238 /* Transform the ray into the superellipsoid space. */
240 MInvTransPoint(P
, Ray
->Initial
, Superellipsoid
->Trans
);
242 MInvTransDirection(D
, Ray
->Direction
, Superellipsoid
->Trans
);
246 VInverseScaleEq(D
, len
);
248 /* Intersect superellipsoid's bounding box. */
250 if (!intersect_box(P
, D
, &t1
, &t2
))
255 /* Test if superellipsoid lies 'behind' the ray origin. */
257 if (t2
< DEPTH_TOLERANCE
)
264 if (t1
< DEPTH_TOLERANCE
)
266 t1
= DEPTH_TOLERANCE
;
272 /* Intersect ray with planes cutting superellipsoids in pieces. */
274 cnt
= find_ray_plane_points(P
, D
, cnt
, dists
, t1
, t2
);
281 VEvaluateRay(P0
, P
, dists
[0], D
)
283 v0
= evaluate_superellipsoid(P0
, Superellipsoid
);
285 if (fabs(v0
) < ZERO_TOLERANCE
)
287 if (insert_hit((OBJECT
*)Superellipsoid
, Ray
, dists
[0] / len
, Depth_Stack
))
289 if (Superellipsoid
->Type
& IS_CHILD_OBJECT
)
300 for (i
= 1; i
< cnt
; i
++)
302 VEvaluateRay(P1
, P
, dists
[i
], D
)
304 v1
= evaluate_superellipsoid(P1
, Superellipsoid
);
306 if (fabs(v1
) < ZERO_TOLERANCE
)
308 if (insert_hit((OBJECT
*)Superellipsoid
, Ray
, dists
[i
] / len
, Depth_Stack
))
310 if (Superellipsoid
->Type
& IS_CHILD_OBJECT
)
324 /* Opposite signs, there must be a root between */
326 solve_hit1(Superellipsoid
, v0
, P0
, v1
, P1
, P2
);
332 if (insert_hit((OBJECT
*)Superellipsoid
, Ray
, t
/ len
, Depth_Stack
))
334 if (Superellipsoid
->Type
& IS_CHILD_OBJECT
)
347 * Although there was no sign change, we may actually be approaching
348 * the surface. In this case, we are being fooled by the shape of the
349 * surface into thinking there isn't a root between sample points.
352 if (check_hit2(Superellipsoid
, P
, D
, dists
[i
-1], P0
, v0
, dists
[i
], &t
, P2
))
354 if (insert_hit((OBJECT
*)Superellipsoid
, Ray
, t
/ len
, Depth_Stack
))
356 if (Superellipsoid
->Type
& IS_CHILD_OBJECT
)
375 Assign_Vector(P0
, P1
);
383 /*****************************************************************************
387 * Inside_Superellipsoid
391 * IPoint - Intersection point
398 * int - TRUE if inside
406 * Test if a point lies inside the superellipsoid.
410 * Oct 1994 : Creation.
412 ******************************************************************************/
414 static int Inside_Superellipsoid(VECTOR IPoint
, OBJECT
*Object
)
418 SUPERELLIPSOID
*Superellipsoid
= (SUPERELLIPSOID
*)Object
;
420 /* Transform the point into the superellipsoid space. */
422 MInvTransPoint(P
, IPoint
, Superellipsoid
->Trans
);
424 val
= evaluate_superellipsoid(P
, Superellipsoid
);
428 return(!Test_Flag(Superellipsoid
, INVERTED_FLAG
));
432 return(Test_Flag(Superellipsoid
, INVERTED_FLAG
));
438 /*****************************************************************************
442 * Superellipsoid_Normal
446 * Result - Normal vector
448 * Inter - Intersection found
462 * Calculate the normal of the superellipsoid in a given point.
466 * Oct 1994 : Creation.
468 ******************************************************************************/
470 static void Superellipsoid_Normal(VECTOR Result
, OBJECT
*Object
, INTERSECTION
*Inter
)
474 SUPERELLIPSOID
*Superellipsoid
= (SUPERELLIPSOID
*)Object
;
476 /* Transform the point into the superellipsoid space. */
478 MInvTransPoint(P
, Inter
->IPoint
, Superellipsoid
->Trans
);
480 Assign_Vector(E
, Superellipsoid
->Power
);
486 k
= power(power(x
, E
[X
]) + power(y
, E
[X
]), E
[Y
] - 1.0);
488 N
[X
] = k
* SGNX(P
[X
]) * power(x
, E
[X
] - 1.0);
489 N
[Y
] = k
* SGNX(P
[Y
]) * power(y
, E
[X
] - 1.0);
490 N
[Z
] = SGNX(P
[Z
]) * power(z
, E
[Z
] - 1.0);
492 /* Transform the normalt out of the superellipsoid space. */
494 MTransNormal(Result
, N
, Superellipsoid
->Trans
);
496 VNormalize(Result
, Result
);
501 /*****************************************************************************
505 * Translate_Superellipsoid
510 * Vector - Translation vector
524 * Translate a superellipsoid.
528 * Oct 1994 : Creation.
530 ******************************************************************************/
532 static void Translate_Superellipsoid(OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
)
534 Transform_Superellipsoid(Object
, Trans
);
539 /*****************************************************************************
543 * Rotate_Superellipsoid
548 * Vector - Rotation vector
562 * Rotate a superellipsoid.
566 * Oct 1994 : Creation.
568 ******************************************************************************/
570 static void Rotate_Superellipsoid(OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
)
572 Transform_Superellipsoid(Object
, Trans
);
577 /*****************************************************************************
581 * Scale_Superellipsoid
586 * Vector - Scaling vector
600 * Scale a superellipsoid.
604 * Oct 1994 : Creation.
606 ******************************************************************************/
608 static void Scale_Superellipsoid(OBJECT
*Object
, VECTOR Vector
, TRANSFORM
*Trans
)
610 Transform_Superellipsoid(Object
, Trans
);
615 /*****************************************************************************
619 * Transform_Superellipsoid
624 * Trans - Transformation to apply
638 * Transform a superellipsoid and recalculate its bounding box.
642 * Oct 1994 : Creation.
644 ******************************************************************************/
646 static void Transform_Superellipsoid(OBJECT
*Object
, TRANSFORM
*Trans
)
648 Compose_Transforms(((SUPERELLIPSOID
*)Object
)->Trans
, Trans
);
650 Compute_Superellipsoid_BBox((SUPERELLIPSOID
*)Object
);
655 /*****************************************************************************
659 * Invert_Superellipsoid
677 * Invert a superellipsoid.
681 * Oct 1994 : Creation.
683 ******************************************************************************/
685 static void Invert_Superellipsoid(OBJECT
*Object
)
687 Invert_Flag(Object
, INVERTED_FLAG
);
692 /*****************************************************************************
696 * Create_Superellipsoid
704 * SUPERELLIPSOID * - new superellipsoid
712 * Create a new superellipsoid.
716 * Oct 1994 : Creation.
718 ******************************************************************************/
720 SUPERELLIPSOID
*Create_Superellipsoid()
724 New
= (SUPERELLIPSOID
*)POV_MALLOC(sizeof(SUPERELLIPSOID
), "superellipsoid");
726 INIT_OBJECT_FIELDS(New
,SUPERELLIPSOID_OBJECT
,&Superellipsoid_Methods
)
728 New
->Trans
= Create_Transform();
730 Make_Vector(New
->Power
, 2.0, 2.0, 2.0);
737 /*****************************************************************************
741 * Copy_Superellipsoid
751 * void * - New superellipsoid
759 * Copy a superellipsoid structure.
763 * Oct 1994 : Creation.
765 ******************************************************************************/
767 static SUPERELLIPSOID
*Copy_Superellipsoid(OBJECT
*Object
)
769 SUPERELLIPSOID
*New
, *Superellipsoid
= (SUPERELLIPSOID
*)Object
;
771 New
= Create_Superellipsoid();
773 /* Get rid of the transformation created in Create_Superellipsoid(). */
775 Destroy_Transform(New
->Trans
);
777 /* Copy superellipsoid. */
779 *New
= *Superellipsoid
;
781 New
->Trans
= Copy_Transform(Superellipsoid
->Trans
);
788 /*****************************************************************************
792 * Destroy_Superellipsoid
810 * Destroy a superellipsoid.
814 * Oct 1994 : Creation.
816 ******************************************************************************/
818 static void Destroy_Superellipsoid(OBJECT
*Object
)
820 SUPERELLIPSOID
*Superellipsoid
= (SUPERELLIPSOID
*)Object
;
822 Destroy_Transform(Superellipsoid
->Trans
);
829 /*****************************************************************************
833 * Compute_Superellipsoid_BBox
837 * Superellipsoid - Superellipsoid
851 * Calculate the bounding box of a superellipsoid.
855 * Oct 1994 : Creation.
857 ******************************************************************************/
859 void Compute_Superellipsoid_BBox(SUPERELLIPSOID
*Superellipsoid
)
861 Make_BBox(Superellipsoid
->BBox
, -1.0001, -1.0001, -1.0001, 2.0002, 2.0002, 2.0002);
863 Recompute_BBox(&Superellipsoid
->BBox
, Superellipsoid
->Trans
);
868 /*****************************************************************************
876 * P, D - Ray origin and direction
877 * dmin, dmax - Intersection depths
893 * Intersect a ray with an axis aligned unit box.
897 * Oct 1994 : Creation.
899 ******************************************************************************/
901 static int intersect_box(VECTOR P
, VECTOR D
, DBL
*dmin
, DBL
*dmax
)
903 DBL tmin
= 0.0, tmax
= 0.0;
907 if (fabs(D
[X
]) > EPSILON
)
911 *dmin
= (MIN_VALUE
- P
[X
]) / D
[X
];
913 *dmax
= (MAX_VALUE
- P
[X
]) / D
[X
];
915 if (*dmax
< EPSILON
) return(FALSE
);
919 *dmax
= (MIN_VALUE
- P
[X
]) / D
[X
];
921 if (*dmax
< EPSILON
) return(FALSE
);
923 *dmin
= (MAX_VALUE
- P
[X
]) / D
[X
];
926 if (*dmin
> *dmax
) return(FALSE
);
930 if ((P
[X
] < MIN_VALUE
) || (P
[X
] > MAX_VALUE
))
941 if (fabs(D
[Y
]) > EPSILON
)
945 tmin
= (MIN_VALUE
- P
[Y
]) / D
[Y
];
947 tmax
= (MAX_VALUE
- P
[Y
]) / D
[Y
];
951 tmax
= (MIN_VALUE
- P
[Y
]) / D
[Y
];
953 tmin
= (MAX_VALUE
- P
[Y
]) / D
[Y
];
958 if (tmax
< EPSILON
) return(FALSE
);
962 if (tmin
> tmax
) return(FALSE
);
968 if (*dmin
> tmax
) return(FALSE
);
977 if (tmin
> *dmax
) return(FALSE
);
985 if ((P
[Y
] < MIN_VALUE
) || (P
[Y
] > MAX_VALUE
))
993 if (fabs(D
[Z
]) > EPSILON
)
997 tmin
= (MIN_VALUE
- P
[Z
]) / D
[Z
];
999 tmax
= (MAX_VALUE
- P
[Z
]) / D
[Z
];
1003 tmax
= (MIN_VALUE
- P
[Z
]) / D
[Z
];
1005 tmin
= (MAX_VALUE
- P
[Z
]) / D
[Z
];
1010 if (tmax
< EPSILON
) return(FALSE
);
1014 if (tmin
> tmax
) return(FALSE
);
1020 if (*dmin
> tmax
) return(FALSE
);
1029 if (tmin
> *dmax
) return(FALSE
);
1037 if ((P
[Z
] < MIN_VALUE
) || (P
[Z
] > MAX_VALUE
))
1051 /*****************************************************************************
1055 * evaluate_superellipsoid
1059 * P - Point to evaluate
1060 * Superellipsoid - Pointer to superellipsoid
1074 * Get superellipsoid value in the given point.
1078 * Oct 1994 : Creation.
1080 ******************************************************************************/
1082 static DBL
evaluate_superellipsoid(VECTOR P
, SUPERELLIPSOID
*Superellipsoid
)
1086 V1
[X
] = power(fabs(P
[X
]), Superellipsoid
->Power
[X
]);
1087 V1
[Y
] = power(fabs(P
[Y
]), Superellipsoid
->Power
[X
]);
1088 V1
[Z
] = power(fabs(P
[Z
]), Superellipsoid
->Power
[Z
]);
1090 return(power(V1
[X
] + V1
[Y
], Superellipsoid
->Power
[Y
]) + V1
[Z
] - 1.0);
1095 /*****************************************************************************
1118 * Raise x to the power of e.
1122 * Oct 1994 : Creation.
1124 ******************************************************************************/
1126 static DBL
power(DBL x
, DBL e
)
1135 /* Test if we have an integer power. */
1141 case 0: return(1.0);
1145 case 2: return(Sqr(b
));
1147 case 3: return(Sqr(b
) * b
);
1149 case 4: b
*= b
; return(Sqr(b
));
1151 case 5: b
*= b
; return(Sqr(b
) * x
);
1153 case 6: b
*= b
; return(Sqr(b
) * b
);
1155 default: return(pow(x
, e
));
1166 /*****************************************************************************
1176 * Depth - Intersection depth
1177 * Depth_Stack - Intersection stack
1185 * int - TRUE, if intersection is valid
1193 * Push an intersection onto the depth stack if it is valid.
1197 * Nov 1994 : Creation.
1199 ******************************************************************************/
1201 static int insert_hit(OBJECT
*Object
, RAY
*Ray
, DBL Depth
, ISTACK
*Depth_Stack
)
1205 if ((Depth
> DEPTH_TOLERANCE
) && (Depth
< Max_Distance
))
1207 VEvaluateRay(IPoint
, Ray
->Initial
, Depth
, Ray
->Direction
);
1209 if (Point_In_Clip(IPoint
, Object
->Clip
))
1211 push_entry(Depth
, IPoint
, Object
, Depth_Stack
);
1222 /*****************************************************************************
1240 * Compare two slabs.
1244 * Nov 1994 : Creation.
1246 ******************************************************************************/
1248 static int compdists(CONST
void *in_a
, CONST
void *in_b
)
1272 /*****************************************************************************
1276 * find_ray_plane_points
1290 * Find all the places where the ray intersects the set of
1291 * subdividing planes through the superquadric. Return the
1292 * number of valid hits (within the bounding box).
1296 * Nov 1994 : Creation.
1298 ******************************************************************************/
1300 static int find_ray_plane_points(VECTOR P
, VECTOR D
, int cnt
, DBL
*dists
, DBL mindist
, DBL maxdist
)
1305 /* Since min and max dist are the distance to two of the bounding planes
1306 we are considering, there is a high probablity of missing them due to
1307 round off error. Therefore we adjust min and max. */
1309 t
= EPSILON
* (maxdist
- mindist
);
1314 /* Check the sets of planes that cut apart the superquadric. */
1316 for (i
= 0; i
< PLANECOUNT
; i
++)
1318 d
= (D
[0] * planes
[i
][0] + D
[1] * planes
[i
][1] + D
[2] * planes
[i
][2]);
1320 if (fabs(d
) < EPSILON
)
1322 /* Can't possibly get a hit for this combination of ray and plane. */
1327 t
= (planes
[i
][3] - (P
[0] * planes
[i
][0] + P
[1] * planes
[i
][1] + P
[2] * planes
[i
][2])) / d
;
1329 if ((t
>= mindist
) && (t
<= maxdist
))
1335 /* Sort the results for further processing. */
1337 QSORT((void *)(dists
), (size_t)cnt
, sizeof(DBL
), compdists
);
1344 /*****************************************************************************
1362 * Home in on the root of a superquadric using a combination of
1363 * secant and bisection methods. This routine requires that
1364 * the sign of the function be different at P0 and P1, it will
1365 * fail drastically if this isn't the case.
1369 * Nov 1994 : Creation.
1371 ******************************************************************************/
1373 static void solve_hit1(SUPERELLIPSOID
*Super
, DBL v0
, VECTOR tP0
, DBL v1
, VECTOR tP1
, VECTOR P
)
1377 VECTOR P0
, P1
, P2
, P3
;
1379 Assign_Vector(P0
, tP0
);
1380 Assign_Vector(P1
, tP1
);
1382 /* The sign of v0 and v1 changes between P0 and P1, this
1383 means there is an intersection point in there somewhere. */
1385 for (i
= 0; i
< MAX_ITERATIONS
; i
++)
1387 if (fabs(v0
) < ZERO_TOLERANCE
)
1389 /* Near point is close enough to an intersection - just use it. */
1391 Assign_Vector(P
, P0
);
1396 if (fabs(v1
) < ZERO_TOLERANCE
)
1398 /* Far point is close enough to an intersection. */
1400 Assign_Vector(P
, P1
);
1405 /* Look at the chord connecting P0 and P1. */
1407 /* Assume a line between the points. */
1409 x
= fabs(v0
) / fabs(v1
- v0
);
1413 VAddScaled(P2
, P0
, x
, P2
);
1415 v2
= evaluate_superellipsoid(P2
, Super
);
1417 /* Look at the midpoint between P0 and P1. */
1421 VAddScaled(P3
, P0
, 0.5, P3
);
1423 v3
= evaluate_superellipsoid(P3
, Super
);
1429 /* This should be impossible, since v0 and v1 were opposite signs,
1430 v2 must be either 0 or opposite in sign to either v0 or v1. */
1432 Error("internal failure in function solve_sq_hit1: %d, %g, %g, %g", i
, v0
, v1
, v2
);
1440 Assign_Vector(P0
, P3
);
1444 Assign_Vector(P0
, P2
);
1449 /* We can move both ends. */
1451 Assign_Vector(P0
, P2
);
1453 Assign_Vector(P1
, P3
);
1461 /* We can move both ends. */
1463 Assign_Vector(P0
, P3
);
1465 Assign_Vector(P1
, P2
);
1471 Assign_Vector(P1
, P2
);
1475 Assign_Vector(P1
, P3
);
1481 if (i
== MAX_ITERATIONS
)
1483 /* The loop never quite closed in on the result - just use the point
1484 closest to zero. This really shouldn't happen since the max number
1485 of iterations is enough to converge with straight bisection. */
1487 if (fabs(v0
) < fabs(v1
))
1489 Assign_Vector(P
, P0
);
1493 Assign_Vector(P
, P1
);
1501 /*****************************************************************************
1519 * Try to find the root of a superquadric using Newtons method.
1523 * Nov 1994 : Creation.
1525 ******************************************************************************/
1527 static int check_hit2(SUPERELLIPSOID
*Super
, VECTOR P
, VECTOR D
, DBL t0
, VECTOR P0
, DBL v0
, DBL t1
, DBL
*t
, VECTOR Q
)
1530 DBL dt0
, dt1
, v1
, deltat
, maxdelta
;
1534 dt1
= t0
+ 0.0001 * (t1
- t0
);
1538 for (i
= 0; (dt0
< t1
) && (i
< MAX_ITERATIONS
); i
++)
1540 VEvaluateRay(P1
, P
, dt1
, D
)
1542 v1
= evaluate_superellipsoid(P1
, Super
);
1546 /* Found a crossing point, go back and use normal root solving. */
1548 solve_hit1(Super
, v0
, P0
, v1
, P1
, Q
);
1558 if (fabs(v1
) < ZERO_TOLERANCE
)
1560 VEvaluateRay(Q
, P
, dt1
, D
)
1568 if (((v0
> 0.0) && (v1
> v0
)) || ((v0
< 0.0) && (v1
< v0
)))
1570 /* We definitely failed */
1582 deltat
= v1
* (dt1
- dt0
) / (v1
- v0
);
1588 if (fabs(deltat
) > maxdelta
)