BRL-CAD
#include "common.h"
#include <stddef.h>
#include <string.h>
#include <math.h>
#include "bio.h"
#include "bu/cv.h"
#include "vmath.h"
#include "db.h"
#include "nmg.h"
#include "rtgeom.h"
#include "raytrace.h"
#include "../../librt_private.h"
Include dependency graph for rhc.c:

Go to the source code of this file.

Data Structures

struct  rhc_specific
 

Macros

#define RHC_NORM_BODY   (1) /* compute normal */
 
#define RHC_NORM_TOP   (2) /* copy rhc_N */
 
#define RHC_NORM_FRT   (3) /* copy reverse rhc_N */
 
#define RHC_NORM_BACK   (4)
 
#define RHC_TOL   .0001
 

Functions

int rt_rhc_bbox (struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *tol)
 
int rt_rhc_prep (struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
 
void rt_rhc_print (const struct soltab *stp)
 
int rt_rhc_shot (struct soltab *stp, struct xray *rp, struct application *ap, struct seg *seghead)
 
void rt_rhc_norm (struct hit *hitp, struct soltab *stp, struct xray *rp)
 
void rt_rhc_curve (struct curvature *cvp, struct hit *hitp, struct soltab *stp)
 
void rt_rhc_uv (struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
 
void rt_rhc_free (struct soltab *stp)
 
int rt_rhc_adaptive_plot (struct rt_db_internal *ip, const struct rt_view_info *info)
 
int rt_rhc_plot (struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info)
 
int rt_mk_hyperbola (struct rt_pt_node *pts, fastf_t r, fastf_t b, fastf_t c, fastf_t dtol, fastf_t ntol)
 
int rt_rhc_tess (struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
 
int rt_rhc_import4 (struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
 
int rt_rhc_export4 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_rhc_import5 (struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
 
int rt_rhc_export5 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_rhc_describe (struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
 
void rt_rhc_ifree (struct rt_db_internal *ip)
 
int rt_rhc_params (struct pc_pc_set *ps, const struct rt_db_internal *ip)
 
void rt_rhc_surf_area (fastf_t *area, const struct rt_db_internal *ip)
 
void rt_rhc_centroid (point_t *cent, const struct rt_db_internal *ip)
 

Variables

const struct bu_structparse rt_rhc_parse []
 

Detailed Description

Intersect a ray with a Right Hyperbolic Cylinder.

Algorithm -

Given V, H, R, and B, there is a set of points on this rhc

{ (x, y, z) | (x, y, z) is on rhc }

Through a series of Affine Transformations, this set of points will be transformed into a set of points on an rhc located at the origin with a rectangular halfwidth R of 1 along the Y axis, a height H of +1 along the -X axis, a distance B of 1 along the -Z axis between the vertex V and the tip of the hyperbola, and a distance c between the tip of the hyperbola and the vertex of the asymptotic cone.

{ (x', y', z') | (x', y', z') is on rhc at origin }

The transformation from X to X' is accomplished by:

X' = S(R(X - V))

where R(X) = (H/(-|H|)) (R/(|R|)) . X (B/(-|B|))

and S(X) = (1/|H| 0 0) (0 1/|R| 0) . X (0 0 1/|B|)

To find the intersection of a line with the surface of the rhc, consider the parametric line L:

L : { P(n) | P + t(n) . D }

Call W the actual point of intersection between L and the rhc. Let W' be the point of intersection between L' and the unit rhc.

L' : { P'(n) | P' + t(n) . D' }

W = invR(invS(W')) + V

Where W' = k D' + P'.

If Dy' and Dz' are both 0, then there is no hit on the rhc; but the end plates need checking. If there is now only 1 hit point, the top plate needs to be checked as well.

Line L' hits the infinitely long canonical rhc at W' when

A * k**2 + B * k + C = 0

where

A = Dz'**2 - Dy'**2 * (1 + 2*c') B = 2 * ((1 + c' + Pz') * Dz' - (1 + 2*c') * Dy' * Py' C = (Pz' + c' + 1)**2 - (1 + 2*c') * Py'**2 - c'**2 b = |Breadth| = 1.0 h = |Height| = 1.0 r = 1.0 c' = c / |Breadth|

The quadratic formula yields k (which is constant):

k = [ -B +/- sqrt(B**2 - 4 * A * C)] / (2 * A)

Now, D' = S(R(D)) and P' = S(R(P - V))

Substituting,

W = V + invR(invS[ k *(S(R(D))) + S(R(P - V)) ]) = V + invR((k * R(D)) + R(P - V)) = V + k * D + P - V = k * D + P

Note that ``k'' is constant, and is the same in the formulations for both W and W'.

The hit at ``k'' is a hit on the canonical rhc IFF -1 <= Wx' <= 0 and -1 <= Wz' <= 0.

NORMALS. Given the point W on the surface of the rhc, what is the vector normal to the tangent plane at that point?

Map W onto the unit rhc, i.e.: W' = S(R(W - V)).

Plane on unit rhc at W' has a normal vector N' where

N' = <0, Wy'*(1 + 2*c), -z-c-1>.

The plane transforms back to the tangent plane at W, and this new plane (on the original rhc) has a normal vector of N, viz:

N = inverse[ transpose(inverse[ S o R ]) ] (N')

because if H is perpendicular to plane Q, and matrix M maps from Q to Q', then inverse[ transpose(M) ] (H) is perpendicular to Q'. Here, H and Q are in "prime space" with the unit sphere. [Somehow, the notation here is backwards]. So, the mapping matrix M = inverse(S o R), because S o R maps from normal space to the unit sphere.

N = inverse[ transpose(inverse[ S o R ]) ] (N') = inverse[ transpose(invR o invS) ] (N') = inverse[ transpose(invS) o transpose(invR) ] (N') = inverse[ inverse(S) o R ] (N') = invR o S (N')

because inverse(R) = transpose(R), so R = transpose(invR), and S = transpose(S).

Note that the normal vector produced above will not have unit length.

THE TOP AND END PLATES.

If Dz' == 0, line L' is parallel to the top plate, so there is no hit on the top plate. Otherwise, rays intersect the top plate with k = (0 - Pz')/Dz'. The solution is within the top plate IFF -1 <= Wx' <= 0 and -1 <= Wy' <= 1.

If Dx' == 0, line L' is parallel to the end plates, so there is no hit on the end plates. Otherwise, rays intersect the front plate line L' hits the front plate with k = (0 - Px') / Dx', and and hits the back plate with k = (-1 - Px') / Dx'.

The solution W' is within an end plate IFF

(Wz' + c + 1)**2 - (Wy'**2 * (2*c + 1) >= c**2 and Wz' <= 1.0

The normal for a hit on the top plate is -Bunit. The normal for a hit on the front plate is -Hunit, and the normal for a hit on the back plate is +Hunit.

Definition in file rhc.c.

Macro Definition Documentation

#define RHC_NORM_BODY   (1) /* compute normal */

Definition at line 369 of file rhc.c.

Referenced by rt_rhc_curve(), rt_rhc_norm(), rt_rhc_shot(), and rt_rhc_uv().

#define RHC_NORM_TOP   (2) /* copy rhc_N */

Definition at line 370 of file rhc.c.

Referenced by rt_rhc_curve(), rt_rhc_norm(), rt_rhc_shot(), and rt_rhc_uv().

#define RHC_NORM_FRT   (3) /* copy reverse rhc_N */

Definition at line 371 of file rhc.c.

Referenced by rt_rhc_curve(), rt_rhc_norm(), rt_rhc_shot(), and rt_rhc_uv().

#define RHC_NORM_BACK   (4)

Definition at line 372 of file rhc.c.

Referenced by rt_rhc_curve(), rt_rhc_norm(), rt_rhc_shot(), and rt_rhc_uv().

#define RHC_TOL   .0001

Referenced by rt_mk_hyperbola().

Function Documentation

int rt_rhc_bbox ( struct rt_db_internal ip,
point_t *  min,
point_t *  max,
const struct bn_tol tol 
)

Calculate the bounding RPP for an RHC

Definition at line 209 of file rhc.c.

References rt_db_internal::idb_ptr, RT_CK_DB_INTERNAL, and VSETALL.

Referenced by rt_rhc_prep().

int rt_rhc_prep ( struct soltab stp,
struct rt_db_internal ip,
struct rt_i rtip 
)

Given a pointer to a GED database record, and a transformation matrix, determine if this is a valid RHC, and if so, precompute various terms of the formula.

Returns - 0 RHC is OK !0 Error in description

Implicit return - A struct rhc_specific is created, and its address is stored in stp->st_specific for use by rhc_shot().

Definition at line 273 of file rhc.c.

References bn_mat_mul(), bn_mat_trn(), BU_GET, ID_RHC, rt_db_internal::idb_ptr, if(), OBJ, R, rhc_specific::rhc_b, rhc_specific::rhc_Bunit, rhc_specific::rhc_c, rhc_specific::rhc_cprime, rhc_specific::rhc_Hunit, rhc_specific::rhc_invRoS, rhc_specific::rhc_rsq, rhc_specific::rhc_Runit, rhc_specific::rhc_SoR, rhc_specific::rhc_V, RT_CK_DB_INTERNAL, RT_CK_RTI, rt_rhc_bbox(), rt_i::rti_tol, soltab::st_aradius, soltab::st_bradius, soltab::st_center, soltab::st_id, soltab::st_max, soltab::st_meth, soltab::st_min, soltab::st_specific, and VSET.

Here is the call graph for this function:

void rt_rhc_print ( const struct soltab stp)

Definition at line 354 of file rhc.c.

References bn_mat_print(), rhc_specific::rhc_Bunit, rhc_specific::rhc_Hunit, rhc_specific::rhc_invRoS, rhc_specific::rhc_Runit, rhc_specific::rhc_SoR, rhc_specific::rhc_V, soltab::st_specific, and VPRINT.

Here is the call graph for this function:

int rt_rhc_shot ( struct soltab stp,
struct xray rp,
struct application ap,
struct seg seghead 
)

Intersect a ray with a rhc. If an intersection occurs, a struct seg will be acquired and filled in.

Returns - 0 MISS >0 HIT

Definition at line 384 of file rhc.c.

References application::a_resource, BU_LIST_INSERT, seg::l, NEAR_ZERO, xray::r_dir, xray::r_pt, rhc_specific::rhc_cprime, RHC_NORM_BACK, RHC_NORM_BODY, RHC_NORM_FRT, RHC_NORM_TOP, rhc_specific::rhc_SoR, rhc_specific::rhc_V, RT_GET_SEG, RT_HIT_MAGIC, RT_PCOEF_TOL, seg::seg_in, seg::seg_out, seg::seg_stp, soltab::st_specific, X, Y, Z, and ZERO.

void rt_rhc_norm ( struct hit hitp,
struct soltab stp,
struct xray rp 
)

Given ONE ray distance, return the normal and entry/exit point.

Definition at line 565 of file rhc.c.

References bu_log(), hit::hit_dist, hit::hit_normal, hit::hit_point, hit::hit_surfno, hit::hit_vpriv, xray::r_dir, xray::r_pt, rhc_specific::rhc_Bunit, rhc_specific::rhc_cprime, rhc_specific::rhc_Hunit, rhc_specific::rhc_invRoS, RHC_NORM_BACK, RHC_NORM_BODY, RHC_NORM_FRT, RHC_NORM_TOP, soltab::st_specific, VSET, Y, and Z.

Here is the call graph for this function:

void rt_rhc_curve ( struct curvature cvp,
struct hit hitp,
struct soltab stp 
)

Return the curvature of the rhc.

Definition at line 608 of file rhc.c.

References bn_vec_ortho(), curvature::crv_c1, curvature::crv_c2, curvature::crv_pdir, hit::hit_normal, hit::hit_point, hit::hit_surfno, rhc_specific::rhc_b, rhc_specific::rhc_c, rhc_specific::rhc_Hunit, RHC_NORM_BACK, RHC_NORM_BODY, RHC_NORM_FRT, RHC_NORM_TOP, rhc_specific::rhc_rsq, soltab::st_specific, and Y.

Here is the call graph for this function:

void rt_rhc_uv ( struct application ap,
struct soltab stp,
struct hit hitp,
struct uvcoord uvp 
)

For a hit on the surface of an rhc, return the (u, v) coordinates of the hit point, 0 <= u, v <= 1 u = azimuth v = elevation

Definition at line 649 of file rhc.c.

References hit::hit_point, hit::hit_surfno, if(), RHC_NORM_BACK, RHC_NORM_BODY, RHC_NORM_FRT, RHC_NORM_TOP, rhc_specific::rhc_SoR, rhc_specific::rhc_V, RT_CK_APPLICATION, soltab::st_specific, uvcoord::uv_du, uvcoord::uv_dv, uvcoord::uv_u, uvcoord::uv_v, X, Y, and Z.

Here is the call graph for this function:

void rt_rhc_free ( struct soltab stp)

Definition at line 696 of file rhc.c.

References BU_PUT, and soltab::st_specific.

int rt_rhc_adaptive_plot ( struct rt_db_internal ip,
const struct rt_view_info info 
)

Definition at line 915 of file rhc.c.

References BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_CK_LIST_HEAD, bu_free(), rt_db_internal::idb_ptr, if(), rt_pt_node::next, primitive_curve_count(), RT_ADD_VLIST, RT_CK_DB_INTERNAL, and rt_view_info::vhead.

Here is the call graph for this function:

int rt_rhc_plot ( struct bu_list vhead,
struct rt_db_internal ip,
const struct rt_tess_tol ttol,
const struct bn_tol tol,
const struct rt_view_info info 
)

Definition at line 981 of file rhc.c.

References OSL::Strings::back, bn_mat_trn(), BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_ALLOC, BU_CK_LIST_HEAD, bu_free(), bu_malloc(), OSL::Strings::front, rt_db_internal::idb_ptr, if(), M_PI, rt_pt_node::next, rt_tess_tol::norm, rt_pt_node::p, primitive_get_absolute_tolerance(), R, RT_ADD_VLIST, RT_CK_DB_INTERNAL, rt_mk_hyperbola(), and VSET.

Here is the call graph for this function:

int rt_mk_hyperbola ( struct rt_pt_node pts,
fastf_t  r,
fastf_t  b,
fastf_t  c,
fastf_t  dtol,
fastf_t  ntol 
)

Definition at line 1101 of file rhc.c.

References A, BU_ALLOC, C, NEAR_ZERO, rt_pt_node::next, rt_pt_node::p, RHC_TOL, VSET, X, Y, and Z.

Referenced by rt_ehy_plot(), rt_ehy_tess(), rt_hrt_plot(), rt_rhc_plot(), and rt_rhc_tess().

int rt_rhc_tess ( struct nmgregion **  r,
struct model *  m,
struct rt_db_internal ip,
const struct rt_tess_tol ttol,
const struct bn_tol tol 
)

Returns - -1 failure 0 OK. *r points to nmgregion that holds this tessellation.

Definition at line 1188 of file rhc.c.

References OSL::Strings::back, BN_CK_TOL, bn_mat_trn(), BU_ALLOC, bu_calloc(), bu_free(), BU_LIST_FIRST, BU_LIST_FOR, bu_malloc(), OSL::Strings::front, rt_db_internal::idb_ptr, if(), M_PI, rt_pt_node::next, nmg_cface(), nmg_find_fu_of_vu(), nmg_fu_planeeqn(), nmg_gluefaces(), nmg_mark_edges_real(), nmg_mrsv(), nmg_region_a(), nmg_vertex_gv(), nmg_vertexuse_nv(), rt_tess_tol::norm, rt_pt_node::p, primitive_get_absolute_tolerance(), R, RT_CK_DB_INTERNAL, RT_CK_TESS_TOL, rt_mk_hyperbola(), s, VSET, Y, and Z.

Here is the call graph for this function:

int rt_rhc_import4 ( struct rt_db_internal ip,
const struct bu_external ep,
const fastf_t mat,
const struct db_i dbip 
)

Import an RHC from the database format to the internal format. Apply modeling transformations as well.

Definition at line 1441 of file rhc.c.

References bn_mat_identity, BU_ALLOC, BU_CK_EXTERNAL, bu_free(), bu_log(), db_i::dbi_version, bu_external::ext_buf, flip_dbfloat(), flip_fastf_float(), ID_RHC, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, if(), OBJ, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_RHC_INTERNAL_MAGIC, SMALL_FASTF, X, and Y.

Here is the call graph for this function:

int rt_rhc_export4 ( struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip 
)

The name is added by the caller, in the usual place.

Definition at line 1513 of file rhc.c.

References bu_calloc(), BU_CK_EXTERNAL, bu_external::ext_buf, bu_external::ext_nbytes, ID_RHC, rt_db_internal::idb_ptr, if(), RT_CK_DB_INTERNAL, and RT_CK_DBI.

Here is the call graph for this function:

int rt_rhc_import5 ( struct rt_db_internal ip,
const struct bu_external ep,
const fastf_t mat,
const struct db_i dbip 
)

Import an RHC from the database format to the internal format. Apply modeling transformations as well.

Definition at line 1557 of file rhc.c.

References bn_mat_identity, BU_ALLOC, BU_ASSERT_LONG, BU_CK_EXTERNAL, bu_cv_ntohd(), bu_free(), bu_log(), bu_external::ext_buf, bu_external::ext_nbytes, ID_RHC, rt_db_internal::idb_major_type, rt_db_internal::idb_meth, rt_db_internal::idb_ptr, OBJ, RT_CK_DB_INTERNAL, RT_CK_DBI, RT_RHC_INTERNAL_MAGIC, SIZEOF_NETWORK_DOUBLE, and SMALL_FASTF.

Here is the call graph for this function:

int rt_rhc_export5 ( struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip 
)

The name is added by the caller, in the usual place.

Definition at line 1608 of file rhc.c.

References BU_CK_EXTERNAL, bu_cv_htond(), bu_malloc(), bu_external::ext_buf, bu_external::ext_nbytes, ID_RHC, rt_db_internal::idb_ptr, if(), RT_CK_DB_INTERNAL, RT_CK_DBI, and SIZEOF_NETWORK_DOUBLE.

Here is the call graph for this function:

int rt_rhc_describe ( struct bu_vls str,
const struct rt_db_internal ip,
int  verbose,
double  mm2local 
)

Make human-readable formatted presentation of this solid. First line describes type of solid. Additional lines are indented one tab, and give parameter values.

Definition at line 1654 of file rhc.c.

References bu_vls_strcat(), rt_db_internal::idb_ptr, X, Y, and Z.

Here is the call graph for this function:

void rt_rhc_ifree ( struct rt_db_internal ip)

Free the storage associated with the rt_db_internal version of this solid.

Definition at line 1701 of file rhc.c.

References bu_free(), rt_db_internal::idb_ptr, and RT_CK_DB_INTERNAL.

Here is the call graph for this function:

int rt_rhc_params ( struct pc_pc_set ps,
const struct rt_db_internal ip 
)

Definition at line 1717 of file rhc.c.

References RT_CK_DB_INTERNAL.

void rt_rhc_surf_area ( fastf_t area,
const struct rt_db_internal ip 
)

n is the number of divisions to use when using Simpson's composite rule below to approximate the integral.

A value of n = 1000000 should be enough to ensure that the approximation is accurate to at least 10 decimal places. The accuracy of the approximation increases by about 2 d.p with each added 0 onto the end of the number (i.e. multiply by 10), so there is a compromise between accuracy and performance, although performance might only be an issue on old slow hardware.

I wouldn't recommend setting this less than about 10000, because this might cause accuracy to be unsuitable for professional or mission critical use.

Definition at line 1757 of file rhc.c.

References A, rt_db_internal::idb_ptr, and RT_CK_DB_INTERNAL.

void rt_rhc_centroid ( point_t *  cent,
const struct rt_db_internal ip 
)

Computes centroid of a right hyperbolic cylinder

Definition at line 1818 of file rhc.c.

References rt_db_internal::idb_ptr, and RT_CK_DB_INTERNAL.

Variable Documentation

const struct bu_structparse rt_rhc_parse[]
Initial value:
= {
{ "%f", 3, "V", bu_offsetofarray(struct rt_rhc_internal, rhc_V, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "H", bu_offsetofarray(struct rt_rhc_internal, rhc_H, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "B", bu_offsetofarray(struct rt_rhc_internal, rhc_B, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 1, "r", bu_offsetof(struct rt_rhc_internal, rhc_r), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 1, "c", bu_offsetof(struct rt_rhc_internal, rhc_c), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ {'\0', '\0', '\0', '\0'}, 0, (char *)NULL, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
}
Definition: color.c:49
#define bu_offsetofarray(_t, _a, _d, _i)
Definition: parse.h:65
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
#define bu_offsetof(_t, _m)
Definition: parse.h:64
double fastf_t
Definition: defines.h:300

Definition at line 195 of file rhc.c.