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 hrt.c:

Go to the source code of this file.

Data Structures

struct  hrt_specific
 

Macros

#define RT_HRT_SEG_MISS(SEG)   (SEG).seg_stp=(struct soltab *) 0;
 
#define HRTOUT(n)   ov+(n-1)*3
 

Functions

int rt_hrt_bbox (struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *tol)
 
int rt_hrt_prep (struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
 
void rt_hrt_print (register const struct soltab *stp)
 
int rt_hrt_shot (struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
 
void rt_hrt_vshot (struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
 
void rt_hrt_norm (register struct hit *hitp, register struct xray *rp)
 
void rt_hrt_curve (void)
 
void rt_hrt_uv (void)
 
void rt_hrt_free (struct soltab *stp)
 
void rt_hrt_24pts (fastf_t *ov, fastf_t *V, fastf_t *A, fastf_t *B)
 
int rt_hrt_adaptive_plot (void)
 
int rt_hrt_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_hrt_tess (void)
 
int rt_hrt_export5 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_hrt_import5 (struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
 
int rt_hrt_describe (struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
 
void rt_hrt_ifree (struct rt_db_internal *ip)
 
int rt_hrt_params (struct pc_pc_set *ps, const struct rt_db_internal *ip)
 
void rt_hrt_surf_area (fastf_t *area, const struct rt_db_internal *ip)
 
void rt_hrt_volume (void)
 
void rt_hrt_centroid (point_t *cent, const struct rt_db_internal *ip)
 

Variables

const struct bu_structparse rt_hrt_parse []
 

Detailed Description

Intersect a ray with a Heart

Algorithm:

Given V, X, Y, Z and d, there is a set of points on this heart

{ (x, y, z) | (x, y, z) is on heart defined by V, X, Y, Z and d }

Through a series of Transformations, this set will be transformed into a set of points on a heart centered at the origin which lies on the X-Y plane (i.e., Z is on the Z axis).

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

The transformation from X to X' is accomplished by:

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

where R(X) = (Z/(|X|)) (Y/(|Y|)) . X (Z/(|Z|))

and S(X) = (1/|A| 0 0) (0 1/|A| 0) . X (0 0 1/|A|) where |A| = d

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

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

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

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

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

Where W' = k D' + P'.

Given a line, find the equation of the heart in terms of the variable 't'.

The equation for the heart is:

[ X**2 + 9/4*Y**2 + Z**2 - 1 ]**3 - Z**3 * (X**2 + 9/80 * Y**2) = 0

First, find X, Y, and Z in terms of 't' for this line, then substitute them into the equation above.

Wx = Dx*t + Px

Wx**3 = Dx**3 * t**3 + 3 * Dx**2 * Px * t**2 + 3 * Dx * Px**2 * t + Px**3

The real roots of the equation in 't' are the intersect points along the parametric line.

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

Map W onto the heart, i.e.: W' = S(R(W - V)). In this case, we find W' by solving the parametric line given k.

The gradient of the heart at W' is in fact the normal vector.

Given that the sextic equation for the heart is:

[ X**2 + 9/4 * Y**2 + Z**2 - 1 ]**3 - Z**3 * (X**2 + 9/80 * Y**2) = 0.

let w = X**2 + 9/4*Y**2 + Z**2 - 1 , then the sextic equation becomes:

w**3 - Y**3 * (X**2 + 9/80 * Y**2) = 0.

For f(x, y, z) = 0, the gradient of f() is (df/dx, df/dy, df/dz).

df/dx = 6 * x * (w**2 - y**3) df/dy = 6 * (12/27 * w**2 * y**2 - 1/2 * y**2 * (x**2 + 9 / 80*z**3)) df/dz = 6 * (w**2 * z - 160 / 9 * y**3 * z**2)

Note that the normal vector produced above will not have length. Also, to make this useful for the original heart, it will have to be rotated back to the orientation of the original heart.

Definition in file hrt.c.

Macro Definition Documentation

#define RT_HRT_SEG_MISS (   SEG)    (SEG).seg_stp=(struct soltab *) 0;

Definition at line 635 of file hrt.c.

Referenced by rt_hrt_vshot().

#define HRTOUT (   n)    ov+(n-1)*3

Similar to code used by the ELL

Definition at line 993 of file hrt.c.

Referenced by rt_hrt_24pts().

Function Documentation

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

Compute the bounding RPP for a heart.

View-points from directly above and besides the heart indicate that it is elliptical, Y-axis is the major axis, X-axis the minor axis and the ratio of the radius of the minor axis to the radius of the major axis is 2/3

1.0 stands for the length of zdir vector and 0.25 closely approximates some value which encloses the displacement from upper cusp to highest point of either lobe in the Z direction

Definition at line 155 of file hrt.c.

References rt_db_internal::idb_ptr, R, X, Y, and Z.

Referenced by rt_hrt_prep().

int rt_hrt_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 heart, and if so, precompute various terms of the formula.

Returns - 0 HRT is OK !0 Error in description

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

1.0 stands for the length of zdir vector and 0.25 closely approximates some value which encloses the displacement from upper cusp to highest point of either lobe in the Z direction

Definition at line 227 of file hrt.c.

References bn_mat_mul(), bn_mat_trn(), BU_GET, bu_log(), bn_tol::dist, hrt_specific::hrt_d, hrt_specific::hrt_invR, hrt_specific::hrt_invRSSR, hrt_specific::hrt_invsq, hrt_specific::hrt_SoR, hrt_specific::hrt_V, hrt_specific::hrt_X, hrt_specific::hrt_Y, hrt_specific::hrt_Z, rt_db_internal::idb_ptr, NEAR_ZERO, R, rt_hrt_bbox(), rt_i::rti_tol, soltab::st_aradius, soltab::st_bradius, soltab::st_center, soltab::st_max, soltab::st_min, soltab::st_specific, VSET, and Z.

Here is the call graph for this function:

void rt_hrt_print ( register const struct soltab stp)

Definition at line 344 of file hrt.c.

References bn_mat_print(), hrt_specific::hrt_invRSSR, hrt_specific::hrt_SoR, hrt_specific::hrt_V, soltab::st_specific, and VPRINT.

Here is the call graph for this function:

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

Intersect a ray with a heart, where all constant terms have been precomputed by rt_hrt_prep(). If an intersection occurs, one or two struct seg(s) will be acquired and filled in.

NOTE: All lines in this function are represented parametrically by a point, P(x0, y0, z0) and a direction normal, D = ax + by + cz. Any point on a line can be expressed by one variable 't', where

X = a*t + x0, e.g., X = Dx*t + Px Y = b*t + y0, Z = c*t + z0.

^ ^ ^ | | |

W = D*t + P

First, convert the line to the coordinate system of a "standard" heart. This is a heart which lies in the X-Y plane, circles the origin, and whose distance to cusps is one.

Then find the equation of that line and the heart, which turns out (by substituting X, Y, Z above into the sextic equation above) to be a sextic equation S in 't' given below.

S(t)=C6*t**6 + C5*t**5 + C4*t**4 + C3*t**3 + C2*t**2 + C1*t + C0 = 0.

where C0, C1, C2, C3, C4, C5, C6 are coefficients of the equation.

Solve the equation using a general polynomial root finder. Use those values of 't' to compute the points of intersection in the original coordinate system.

Returns - 0 MISS >0 HIT

Generate the sextic equation S(t) = 0 to be passed through the root finder.

Definition at line 394 of file hrt.c.

References A, application::a_resource, application::a_rt_i, bn_pr_roots(), BU_LIST_INSERT, bu_log(), directory::d_namep, bn_tol::dist, hrt_specific::hrt_SoR, hrt_specific::hrt_V, seg::l, NEAR_ZERO, xray::r_dir, xray::r_pt, RT_GET_SEG, rt_poly_roots(), rt_i::rti_tol, soltab::st_dp, soltab::st_specific, OSL::Strings::u, VPRINT, X, Y, and Z.

Here is the call graph for this function:

void rt_hrt_vshot ( struct soltab **  stp,
struct xray **  rp,
struct seg segp,
int  n,
struct application ap 
)

This is the Becker vector version

Definition at line 640 of file hrt.c.

References A, application::a_rt_i, bn_pr_roots(), bu_free(), bu_log(), bu_malloc(), bn_poly::cf, bn_poly::dgr, bn_tol::dist, hit::hit_dist, hit::hit_normal, hrt_specific::hrt_SoR, hrt_specific::hrt_V, NEAR_ZERO, xray::r_dir, RT_HRT_SEG_MISS, rt_poly_roots(), rt_pt_sort(), rt_i::rti_tol, seg::seg_in, seg::seg_out, VPRINT, X, Y, and Z.

Here is the call graph for this function:

void rt_hrt_norm ( register struct hit hitp,
register struct xray rp 
)

Compute the normal to the heart, given a point on the heart centered at the origin on the X-Y plane. The gradient of the heart at that point is in fact the normal vector, which will have to be given unit length. To make this useful for the original heart, it will have to be rotated back to the orientation of the original heart.

Given that the equation for the heart is:

[ X**2 + 9/4 * Y**2 + Z**2 - 1 ]**3 - Z**3 * (X**2 + 9/80*Y**2) = 0.

let w = X**2 + 9/4 * Y**2 + Z**2 - 1, then the equation becomes:

w**3 - Z**3 * (X**2 + 9/80 * Y**2) = 0.

For f(x, y, z) = 0, the gradient of f() is (df/dx, df/dy, df/dz).

df/dx = 6 * X * (w**2 - Z**3/3) df/dy = 6 * Y * (12/27 * w**2 - 80/3 * Z**3) df/dz = 6 * Z * ( w**2 - 1/2 * Z * (X**2 + 9/80 * Y**2))

Since we rescale the gradient (normal) to unity, we divide the above equations by six here.

Definition at line 944 of file hrt.c.

References hit::hit_dist, hit::hit_normal, hit::hit_point, hit::hit_vpriv, xray::r_dir, xray::r_pt, VSET, X, Y, and Z.

void rt_hrt_curve ( void  )

Return the curvature of the heart.

Definition at line 966 of file hrt.c.

References bu_log().

Here is the call graph for this function:

void rt_hrt_uv ( void  )

Definition at line 973 of file hrt.c.

References bu_log().

Here is the call graph for this function:

void rt_hrt_free ( struct soltab stp)

Definition at line 980 of file hrt.c.

References BU_PUT, and soltab::st_specific.

void rt_hrt_24pts ( fastf_t ov,
fastf_t V,
fastf_t A,
fastf_t B 
)

Definition at line 995 of file hrt.c.

References HRTOUT.

Referenced by rt_hrt_plot().

int rt_hrt_adaptive_plot ( void  )

Definition at line 1042 of file hrt.c.

References bu_log().

Here is the call graph for this function:

int rt_hrt_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 1050 of file hrt.c.

References A, bn_mat_trn(), BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_ALLOC, BU_CK_LIST_HEAD, bu_free(), bu_malloc(), ell_angle(), rt_db_internal::idb_ptr, M_PI, rt_pt_node::next, rt_pt_node::p, primitive_get_absolute_tolerance(), R, RT_ADD_VLIST, RT_CK_DB_INTERNAL, rt_ell(), rt_hrt_24pts(), rt_mk_hyperbola(), top(), VSET, X, Y, and Z.

Here is the call graph for this function:

int rt_hrt_tess ( void  )

Definition at line 1508 of file hrt.c.

References bu_log().

Here is the call graph for this function:

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

The external form is: V point Xdir vector Ydir vector Zdir vector

Definition at line 1523 of file hrt.c.

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

Here is the call graph for this function:

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

Import a heart from the database format to the internal format.

Definition at line 1560 of file hrt.c.

References bn_mat_identity, BU_ALLOC, BU_ASSERT_LONG, BU_CK_EXTERNAL, bu_cv_ntohd(), bu_external::ext_buf, bu_external::ext_nbytes, ID_HRT, 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_HRT_INTERNAL_MAGIC, and SIZEOF_NETWORK_DOUBLE.

Here is the call graph for this function:

int rt_hrt_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 1603 of file hrt.c.

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

Here is the call graph for this function:

void rt_hrt_ifree ( struct rt_db_internal ip)

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

Definition at line 1672 of file hrt.c.

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

Here is the call graph for this function:

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

Definition at line 1687 of file hrt.c.

References RT_CK_DB_INTERNAL.

void rt_hrt_surf_area ( fastf_t area,
const struct rt_db_internal ip 
)

Definition at line 1696 of file hrt.c.

References rt_db_internal::idb_ptr, M_PI, Y, and Z.

void rt_hrt_volume ( void  )

Definition at line 1713 of file hrt.c.

References bu_log().

Here is the call graph for this function:

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

Computes centroid of a heart

Definition at line 1722 of file hrt.c.

References rt_db_internal::idb_ptr, VSET, X, Y, and Z.

Variable Documentation

const struct bu_structparse rt_hrt_parse[]
Initial value:
= {
{ "%f", 3, "V", bu_offsetofarray(struct rt_hrt_internal, v, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "X", bu_offsetofarray(struct rt_hrt_internal, xdir, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "Y", bu_offsetofarray(struct rt_hrt_internal, ydir, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%f", 3, "Z", bu_offsetofarray(struct rt_hrt_internal, zdir, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
{ "%g", 1, "d", bu_offsetof(struct rt_hrt_internal, d), 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 128 of file hrt.c.