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

Go to the source code of this file.

Data Structures

struct  tor_specific
 

Macros

#define RT_TOR_SEG_MISS(SEG)   (SEG).seg_stp=(struct soltab *) 0;
 
#define TOR_PT(www, lll)   ((((www)%nw)*nlen)+((lll)%nlen))
 
#define TOR_PTA(ww, ll)   (&pts[TOR_PT(ww, ll)*3])
 
#define TOR_NORM_A(ww, ll)   (&norms[TOR_PT(ww, ll)*3])
 

Functions

int rt_tor_bbox (struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *tol)
 
int rt_tor_prep (struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
 
void rt_tor_print (register const struct soltab *stp)
 
int rt_tor_shot (struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
 
void rt_tor_vshot (struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
 
void rt_tor_norm (register struct hit *hitp, struct soltab *stp, register struct xray *rp)
 
void rt_tor_curve (register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
 
void rt_tor_uv (struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
 
void rt_tor_free (struct soltab *stp)
 
int rt_num_circular_segments (double maxerr, double radius)
 
int rt_tor_adaptive_plot (struct rt_db_internal *ip, const struct rt_view_info *info)
 
int rt_tor_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_tor_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_tor_import4 (struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
 
int rt_tor_export5 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_tor_export4 (struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
 
int rt_tor_import5 (struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
 
int rt_tor_describe (struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
 
void rt_tor_ifree (struct rt_db_internal *ip)
 
int rt_tor_params (struct pc_pc_set *ps, const struct rt_db_internal *ip)
 
void rt_tor_surf_area (fastf_t *area, const struct rt_db_internal *ip)
 
void rt_tor_volume (fastf_t *vol, const struct rt_db_internal *ip)
 
void rt_tor_centroid (point_t *cent, const struct rt_db_internal *ip)
 

Variables

const struct bu_structparse rt_tor_parse []
 

Detailed Description

Intersect a ray with a Torus

Algorithm:

Given V, H, A, and B, there is a set of points on this torus

{ (x, y, z) | (x, y, z) is on torus defined by V, H, A, B }

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

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

The transformation from X to X' is accomplished by:

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

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

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

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

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

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

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

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

Where W' = k D' + P'.

Given a line and a ratio, alpha, finds the equation of the unit torus in terms of the variable 't'.

The equation for the torus is:

[ X**2 + Y**2 + Z**2 + (1 - alpha**2) ]**2 - 4*(X**2 + 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**2 = Dx**2 * t**2 + 2 * Dx * Px + Px**2

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

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

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

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

Given that the equation for the unit torus is:

[ X**2 + Y**2 + Z**2 + (1 - alpha**2) ]**2 - 4*(X**2 + Y**2) = 0

let w = X**2 + Y**2 + Z**2 + (1 - alpha**2), then the equation becomes:

w**2 - 4*(X**2 + Y**2) = 0

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

df/dx = 2 * w * 2 * x - 8 * x = (4 * w - 8) * x df/dy = 2 * w * 2 * y - 8 * y = (4 * w - 8) * y df/dz = 2 * w * 2 * z = 4 * w * z

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

Definition in file tor.c.

Macro Definition Documentation

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

Definition at line 534 of file tor.c.

Referenced by rt_tor_vshot().

#define TOR_PT (   www,
  lll 
)    ((((www)%nw)*nlen)+((lll)%nlen))

Referenced by rt_tor_tess().

#define TOR_PTA (   ww,
  ll 
)    (&pts[TOR_PT(ww, ll)*3])

Referenced by rt_tor_plot(), and rt_tor_tess().

#define TOR_NORM_A (   ww,
  ll 
)    (&norms[TOR_PT(ww, ll)*3])

Referenced by rt_tor_tess().

Function Documentation

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

Compute the bounding RPP for a circular torus.

Definition at line 161 of file tor.c.

References rt_db_internal::idb_ptr, OSL::Strings::P, VSET, X, Y, and Z.

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

Returns - 0 TOR is OK !0 Error in description

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

Definition at line 220 of file tor.c.

References bn_mat_inv(), BU_GET, bu_log(), bn_tol::dist, rt_functab::ft_bbox, rt_db_internal::idb_ptr, NEAR_ZERO, R, rt_i::rti_tol, soltab::st_aradius, soltab::st_bradius, soltab::st_center, soltab::st_max, soltab::st_meth, soltab::st_min, soltab::st_specific, tor_specific::tor_alpha, tor_specific::tor_invR, tor_specific::tor_N, tor_specific::tor_r1, tor_specific::tor_r2, tor_specific::tor_SoR, and tor_specific::tor_V.

Here is the call graph for this function:

void rt_tor_print ( register const struct soltab stp)

Definition at line 301 of file tor.c.

References bn_mat_print(), bu_log(), soltab::st_specific, tor_specific::tor_alpha, tor_specific::tor_invR, tor_specific::tor_N, tor_specific::tor_r1, tor_specific::tor_r2, tor_specific::tor_SoR, tor_specific::tor_V, and VPRINT.

Here is the call graph for this function:

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

Intersect a ray with an torus, where all constant terms have been precomputed by rt_tor_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.

First, convert the line to the coordinate system of a "standard" torus. This is a torus which lies in the X-Y plane, circles the origin, and whose primary radius is one. The secondary radius is alpha = (R2/R1) of the original torus where (0 < alpha <= 1).

Then find the equation of that line and the standard torus, which turns out to be a quartic equation in 't'. 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

Definition at line 345 of file tor.c.

References A, application::a_resource, application::a_rt_i, bn_pr_roots(), BU_LIST_INSERT, bu_log(), C, directory::d_namep, bn_tol::dist, 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, tor_specific::tor_alpha, tor_specific::tor_r1, tor_specific::tor_SoR, tor_specific::tor_V, OSL::Strings::u, VPRINT, X, Y, and Z.

Here is the call graph for this function:

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

This is the Becker vector version

Definition at line 539 of file tor.c.

References A, application::a_rt_i, bn_pr_roots(), bu_free(), bu_log(), bu_malloc(), C, bn_poly::cf, bn_poly::dgr, bn_tol::dist, hit::hit_dist, hit::hit_normal, NEAR_ZERO, xray::r_dir, rt_poly_roots(), rt_pt_sort(), RT_TOR_SEG_MISS, rt_i::rti_tol, seg::seg_in, seg::seg_out, tor_specific::tor_alpha, tor_specific::tor_r1, tor_specific::tor_SoR, tor_specific::tor_V, VPRINT, X, Y, and Z.

Here is the call graph for this function:

void rt_tor_norm ( register struct hit hitp,
struct soltab stp,
register struct xray rp 
)

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

Given that the equation for the unit torus is:

 [ X**2 + Y**2 + Z**2 + (1 - alpha**2) ]**2 - 4*(X**2 + Y**2)  =  0

let w = X**2 + Y**2 + Z**2 + (1 - alpha**2), then the equation becomes:

 w**2 - 4*(X**2 + Y**2)  =  0

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

 df/dx = 2 * w * 2 * x - 8 * x      = (4 * w - 8) * x
 df/dy = 2 * w * 2 * y - 8 * y      = (4 * w - 8) * y
 df/dz = 2 * w * 2 * z              = 4 * w * z

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

Definition at line 808 of file tor.c.

References hit::hit_dist, hit::hit_normal, hit::hit_point, hit::hit_vpriv, xray::r_dir, xray::r_pt, soltab::st_specific, tor_specific::tor_alpha, tor_specific::tor_invR, VSET, X, Y, and Z.

void rt_tor_curve ( register struct curvature cvp,
register struct hit hitp,
struct soltab stp 
)
void rt_tor_uv ( struct application ap,
struct soltab stp,
struct hit hitp,
struct uvcoord uvp 
)

Definition at line 878 of file tor.c.

References hit::hit_point, if(), RT_CK_APPLICATION, RT_CK_HIT, RT_CK_SOLTAB, soltab::st_specific, tor_specific::tor_SoR, tor_specific::tor_V, uvcoord::uv_u, uvcoord::uv_v, VSET, X, Y, and Z.

Here is the call graph for this function:

void rt_tor_free ( struct soltab stp)

Definition at line 909 of file tor.c.

References BU_PUT, and soltab::st_specific.

int rt_num_circular_segments ( double  maxerr,
double  radius 
)

Given a circle with a specified radius, determine the minimum number of straight line segments that the circle can be approximated with, while still meeting the given maximum permissible error distance. Form a chord (straight line) by connecting the start and end points found when sweeping a 'radius' arc through angle 'theta'.

The error distance is the distance between where a radius line at angle theta/2 hits the chord, and where it hits the circle (at 'radius' distance).

error_distance = radius * (1 - cos(theta/2))

or

theta = 2 * acos(1 - error_distance / radius)

Returns - number of segments. Always at least 6.

Definition at line 940 of file tor.c.

References M_PI, and SMALL_FASTF.

Referenced by rt_eto_plot(), rt_eto_tess(), rt_tor_plot(), and rt_tor_tess().

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

Definition at line 992 of file tor.c.

References BU_CK_LIST_HEAD, ellipse_point_at_radian(), rt_db_internal::idb_ptr, plot_ellipse(), primitive_curve_count(), RT_CK_DB_INTERNAL, and rt_view_info::vhead.

Here is the call graph for this function:

int rt_tor_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 
)

The TORUS has the following input fields: ti.v V from origin to center ti.h Radius Vector, Normal to plane of torus ti.a, ti.b perpendicular, to CENTER of torus (for top, bottom)

Definition at line 1084 of file tor.c.

References rt_tess_tol::abs, OSL::Strings::alpha, BN_VLIST_LINE_DRAW, BN_VLIST_LINE_MOVE, BU_CK_LIST_HEAD, bu_free(), bu_malloc(), rt_db_internal::idb_ptr, M_PI, rt_tess_tol::norm, primitive_get_absolute_tolerance(), rt_tess_tol::rel, RT_ADD_VLIST, RT_CK_DB_INTERNAL, rt_num_circular_segments(), and TOR_PTA.

Here is the call graph for this function:

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

Definition at line 1201 of file tor.c.

References rt_tess_tol::abs, OSL::Strings::alpha, bu_calloc(), bu_free(), BU_LIST_FIRST, BU_LIST_FOR, bu_log(), bu_malloc(), rt_db_internal::idb_ptr, M_PI, nmg_cmface(), nmg_find_fu_of_vu(), nmg_fu_planeeqn(), nmg_keu_zl(), nmg_mrsv(), nmg_region_a(), nmg_vertex_gv(), nmg_vertexuse_nv(), rt_tess_tol::norm, rt_tess_tol::rel, RT_CK_DB_INTERNAL, rt_num_circular_segments(), s, TOR_NORM_A, TOR_PT, and TOR_PTA.

Here is the call graph for this function:

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

Import a torus from the database format to the internal format. Apply modeling transformations at the same time.

Definition at line 1380 of file tor.c.

References bn_mat_identity, BU_ALLOC, BU_CK_EXTERNAL, bu_log(), db_i::dbi_version, bu_external::ext_buf, flip_fastf_float(), ID_TOR, 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_TOR_INTERNAL_MAGIC, and SMALL_FASTF.

Here is the call graph for this function:

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

Definition at line 1441 of file tor.c.

References BU_CK_EXTERNAL, bu_cv_htond(), bu_malloc(), bu_external::ext_buf, bu_external::ext_nbytes, ID_TOR, 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_tor_export4 ( struct bu_external ep,
const struct rt_db_internal ip,
double  local2mm,
const struct db_i dbip 
)

The name will be added by the caller.

Definition at line 1476 of file tor.c.

References bn_vec_ortho(), bu_calloc(), BU_CK_EXTERNAL, bu_log(), bu_external::ext_buf, bu_external::ext_nbytes, ID_TOR, rt_db_internal::idb_ptr, if(), RT_CK_DB_INTERNAL, RT_CK_DBI, and SQRT_SMALL_FASTF.

Here is the call graph for this function:

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

Taken from the database record: v vertex (point) of center of torus. h unit vector in the normal direction of the torus major radius of ring from 'v' to center of ring minor radius of the ring

Calculate: 2nd radius of ring (==1st radius) ring unit vector 1 ring unit vector 2

Definition at line 1571 of file tor.c.

References bn_mat_identity, bn_mat_is_non_unif(), bn_vec_ortho(), BU_ALLOC, BU_ASSERT_LONG, BU_CK_EXTERNAL, bu_cv_ntohd(), bu_log(), bu_external::ext_buf, bu_external::ext_nbytes, ID_TOR, 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_TOR_INTERNAL_MAGIC, SIZEOF_NETWORK_DOUBLE, and OSL::Strings::v.

Here is the call graph for this function:

int rt_tor_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 1632 of file tor.c.

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

Here is the call graph for this function:

void rt_tor_ifree ( struct rt_db_internal ip)

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

Definition at line 1686 of file tor.c.

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

Here is the call graph for this function:

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

Definition at line 1701 of file tor.c.

References RT_CK_DB_INTERNAL.

void rt_tor_surf_area ( fastf_t area,
const struct rt_db_internal ip 
)

Definition at line 1710 of file tor.c.

References rt_db_internal::idb_ptr, and M_PI.

void rt_tor_volume ( fastf_t vol,
const struct rt_db_internal ip 
)

Definition at line 1722 of file tor.c.

References rt_db_internal::idb_ptr, and M_PI.

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

Definition at line 1731 of file tor.c.

References rt_db_internal::idb_ptr.

Variable Documentation

const struct bu_structparse rt_tor_parse[]
Initial value:
= {
{"%f", 3, "V", bu_offsetofarray(struct rt_tor_internal, v, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL},
{"%f", 3, "H", bu_offsetofarray(struct rt_tor_internal, h, fastf_t, X), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL},
{"%f", 1, "r_a", bu_offsetof(struct rt_tor_internal, r_a), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL},
{"%f", 1, "r_h", bu_offsetof(struct rt_tor_internal, r_h), 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 138 of file tor.c.