BRL-CAD
mkbundle.c
Go to the documentation of this file.
1 /* M K B U N D L E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup librt */
21 /** @{ */
22 /** @file librt/mkbundle.c
23  *
24  */
25 /** @} */
26 
27 #include "common.h"
28 
29 #include <math.h>
30 #include "bio.h"
31 
32 #include "vmath.h"
33 
34 #include "bn.h"
35 #include "raytrace.h"
36 
37 
38 /**
39  * Make a bundle of rays around a main ray, with a circular exterior,
40  * and spiral filling of the interior. The outer periphery is sampled
41  * with rays_per_ring additional rays, preferably at least 3.
42  *
43  * rp[] must be of size (rays_per_ring*nring)+1. Entry 0 is the main
44  * ray, and must be provided by the caller. The remaining entries
45  * will be filled in with extra rays. The radius of the bundle is
46  * given in mm.
47  *
48  * rp[0].r_dir must have unit length.
49  *
50  * XXX Should we require a and b as inputs, for efficiency?
51  */
52 
53 int
54 rt_raybundle_maker(struct xray *rp, double radius, const fastf_t *avec, const fastf_t *bvec, int rays_per_ring, int nring)
55 {
56  register struct xray *rayp = rp+1;
57  int ring;
58  double fraction = 1.0;
59  double theta;
60  double delta;
61  double radial_scale;
62  int count = 0;
63 
64  rp[0].index = count++;
65  rp[0].magic =RT_RAY_MAGIC;
66 
67  for (ring=0; ring < nring; ring++) {
68  register int i;
69 
70  theta = 0;
71  delta = M_2PI / rays_per_ring;
72  fraction = ((double)(ring+1)) / nring;
73  theta = delta * fraction; /* spiral skew */
74  radial_scale = radius * fraction;
75  for (i=0; i < rays_per_ring; i++) {
76  register double ct, st;
77  /* pt = V + cos(theta) * A + sin(theta) * B */
78  ct = cos(theta) * radial_scale;
79  st = sin(theta) * radial_scale;
80  VJOIN2(rayp->r_pt, rp[0].r_pt, ct, avec, st, bvec);
81  VMOVE(rayp->r_dir, rp[0].r_dir);
82  rayp->index = count++;
83  rayp->magic = RT_RAY_MAGIC;
84  theta += delta;
85  rayp++;
86  }
87  }
88  return count;
89 }
90 
91 
92 int
93 rt_gen_circular_grid(struct xrays *rays, const struct xray *center_ray, fastf_t radius, const fastf_t *up_vector, fastf_t gridsize)
94 {
95  vect_t dir;
96  vect_t avec;
97  vect_t bvec;
98  vect_t uvec;
99 
100  VMOVE(dir, center_ray->r_dir);
101  VMOVE(uvec, up_vector);
102  VUNITIZE(uvec);
103  VSCALE(bvec, uvec, radius);
104 
105  VCROSS(avec, dir, up_vector);
106  VUNITIZE(avec);
107  VSCALE(avec, avec, radius);
108 
109  return rt_gen_elliptical_grid(rays, center_ray, avec, bvec, gridsize);
110 }
111 
112 
113 int
114 rt_gen_elliptical_grid(struct xrays *rays, const struct xray *center_ray, const fastf_t *avec, const fastf_t *bvec, fastf_t gridsize)
115 {
116  register struct xrays *xrayp;
117  int count = 0;
118  point_t C;
119  vect_t dir;
120  vect_t a_dir;
121  vect_t b_dir;
122 
123  fastf_t a = MAGNITUDE(avec);
124  fastf_t b = MAGNITUDE(bvec);
125  fastf_t x, y;
126 
127  int acpr = a / gridsize;
128  int bcpr = b / gridsize;
129 
130  VMOVE(a_dir, avec);
131  VUNITIZE(a_dir);
132 
133  VMOVE(b_dir, bvec);
134  VUNITIZE(b_dir);
135 
136  VMOVE(C, center_ray->r_pt);
137  VMOVE(dir, center_ray->r_dir);
138  /* make sure avec perpendicular to bvec perpendicular to ray direction */
139  BU_ASSERT(NEAR_ZERO(VDOT(avec, bvec), VUNITIZE_TOL));
140  BU_ASSERT(NEAR_ZERO(VDOT(avec, dir), VUNITIZE_TOL));
141 
142  for (y=gridsize * (-bcpr); y <= b; y=y+gridsize) {
143  for (x= gridsize * (-acpr); x <= a; x=x+gridsize) {
144  if (((x*x)/(a*a) + (y*y)/(b*b)) < 1) {
145  BU_ALLOC(xrayp, struct xrays);
146  VJOIN2(xrayp->ray.r_pt, C, x, a_dir, y, b_dir);
147  VMOVE(xrayp->ray.r_dir, dir);
148  xrayp->ray.index = count++;
149  xrayp->ray.magic = RT_RAY_MAGIC;
150  BU_LIST_APPEND(&rays->l, &xrayp->l);
151  }
152  }
153  }
154  return count;
155 }
156 
157 int
158 rt_gen_conic(struct xrays *rays, const struct xray *center_ray,
159  fastf_t theta, vect_t up_vector, int rays_per_radius)
160 {
161  int count = 0;
162 
163  point_t start;
164  vect_t orig_dir;
165 
166  fastf_t x, y;
167 
168  /* Setting radius to tan(theta) works because, as shown in the
169  * following diagram, the ray that starts at the given point and
170  * passes through orig_dir + (radius in any orthogonal direction)
171  * has an angle of theta with the original ray; when the
172  * resulting vector is normalized, the angle is preserved.
173  */
174  fastf_t radius = tan(theta);
175  fastf_t rsq = radius * radius; /* radius-squared, for use in the loop */
176 
177  fastf_t gridsize = 2 * radius / (rays_per_radius - 1);
178 
179  vect_t a_dir, b_dir;
180 
181  register struct xrays *xrayp;
182 
183  VMOVE(start, center_ray->r_pt);
184  VMOVE(orig_dir, center_ray->r_dir);
185 
186  /* Create vectors a_dir, b_dir that are orthogonal to orig_dir. */
187  VMOVE(b_dir, up_vector);
188  VUNITIZE(b_dir);
189 
190  VCROSS(a_dir, orig_dir, up_vector);
191  VUNITIZE(a_dir);
192 
193  for (y = -radius; y <= radius; y += gridsize) {
194  vect_t tmp;
195  printf("y:%f\n", y);
196  VSCALE(tmp, b_dir, y);
197  printf("y_partofit: %f,%f,%f\n", V3ARGS(tmp));
198  for (x = -radius; x <= radius; x += gridsize) {
199  if (((x*x)/rsq + (y*y)/rsq) <= 1) {
200  BU_ALLOC(xrayp, struct xrays);
201  VMOVE(xrayp->ray.r_pt, start);
202  VJOIN2(xrayp->ray.r_dir, orig_dir, x, a_dir, y, b_dir);
203  VUNITIZE(xrayp->ray.r_dir);
204  xrayp->ray.index = count++;
205  xrayp->ray.magic = RT_RAY_MAGIC;
206  BU_LIST_APPEND(&rays->l, &xrayp->l);
207  }
208  }
209  }
210  return count;
211 }
212 
213 
214 
215 
216 int
217 rt_gen_frustum(struct xrays *rays, const struct xray *center_ray,
218  const vect_t a_vec, const vect_t b_vec,
219  const fastf_t a_theta, const fastf_t b_theta,
220  const fastf_t a_num, const fastf_t UNUSED(b_num))
221 {
222  int count = 0;
223 
224  point_t start;
225  vect_t orig_dir;
226 
227  fastf_t x, y;
228 
229  fastf_t a_length = tan(a_theta);
230  fastf_t b_length = tan(b_theta);
231  fastf_t a_inc = 2 * a_length / (a_num - 1);
232 
233  vect_t a_dir, b_dir;
234 
235  register struct xrays *xrayp;
236 
237  VMOVE(start, center_ray->r_pt);
238  VMOVE(orig_dir, center_ray->r_dir);
239 
240  VMOVE(a_dir, a_vec);
241  VUNITIZE(a_dir);
242  VMOVE(b_dir, b_vec);
243  VUNITIZE(b_dir);
244 
245  /* This adds BN_TOL_DIST to the *_length variables in the
246  * condition because in some cases, floating-point problems can
247  * make extremely close numbers compare incorrectly. */
248  for (y = -b_length; y <= b_length + BN_TOL_DIST;) {
249  for (x = -a_length; x <= a_length + BN_TOL_DIST; x += a_inc) {
250  BU_ALLOC(xrayp, struct xrays);
251  VMOVE(xrayp->ray.r_pt, start);
252  VJOIN2(xrayp->ray.r_dir, orig_dir, x, a_dir, y, b_dir);
253  VUNITIZE(xrayp->ray.r_dir);
254  xrayp->ray.index = count++;
255  xrayp->ray.magic = RT_RAY_MAGIC;
256  BU_LIST_APPEND(&rays->l, &xrayp->l);
257  }
258  }
259  return count;
260 }
261 
262 int rt_gen_rect(struct xrays *rays, const struct xray *center_ray,
263  const vect_t a_vec, const vect_t b_vec,
264  const fastf_t da, const fastf_t db)
265 {
266  int count = 0;
267 
268  point_t orig_start;
269  vect_t dir;
270 
271  fastf_t x, y;
272 
273  fastf_t a_length = MAGNITUDE(a_vec);
274  fastf_t b_length = MAGNITUDE(b_vec);
275 
276  vect_t a_dir;
277  vect_t b_dir;
278 
279  register struct xrays *xrayp;
280 
281  VMOVE(orig_start, center_ray->r_pt);
282  VMOVE(dir, center_ray->r_dir);
283 
284  VMOVE(a_dir, a_vec);
285  VUNITIZE(a_dir);
286 
287  VMOVE(b_dir, b_vec);
288  VUNITIZE(b_dir);
289 
290  for (y = -b_length; y <= b_length; y += db) {
291  for (x = -a_length; x <= a_length; x += da) {
292  BU_ALLOC(xrayp, struct xrays);
293  VJOIN2(xrayp->ray.r_pt, orig_start, x, a_dir, y, b_dir);
294  VMOVE(xrayp->ray.r_dir, dir);
295  xrayp->ray.index = count++;
296  xrayp->ray.magic = RT_RAY_MAGIC;
297  BU_LIST_APPEND(&rays->l, &xrayp->l);
298  }
299  }
300  return count;
301 }
302 
303 /*
304  * Local Variables:
305  * mode: C
306  * tab-width: 8
307  * indent-tabs-mode: t
308  * c-file-style: "stroustrup"
309  * End:
310  * ex: shiftwidth=4 tabstop=8
311  */
fastf_t C[2 *MAX_CNT+1][2 *MAX_CNT+1]
Definition: dsp_brep.cpp:38
#define RT_RAY_MAGIC
Definition: magic.h:165
int rt_gen_elliptical_grid(struct xrays *rays, const struct xray *center_ray, const fastf_t *avec, const fastf_t *bvec, fastf_t gridsize)
Definition: mkbundle.c:114
struct bu_list l
Definition: raytrace.h:233
Definition: raytrace.h:215
#define st
Header file for the BRL-CAD common definitions.
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
#define BU_ASSERT(_equation)
Definition: defines.h:216
int index
Which ray of a bundle.
Definition: raytrace.h:217
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
int rt_raybundle_maker(struct xray *rp, double radius, const fastf_t *avec, const fastf_t *bvec, int rays_per_ring, int nring)
Definition: mkbundle.c:54
#define V3ARGS(a)
Definition: color.c:56
#define NEAR_ZERO(val, epsilon)
Definition: color.c:55
int rt_gen_rect(struct xrays *rays, const struct xray *center_ray, const vect_t a_vec, const vect_t b_vec, const fastf_t da, const fastf_t db)
Definition: mkbundle.c:262
#define BN_TOL_DIST
Definition: tol.h:109
#define UNUSED(parameter)
Definition: common.h:239
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
int rt_gen_circular_grid(struct xrays *rays, const struct xray *center_ray, fastf_t radius, const fastf_t *up_vector, fastf_t gridsize)
Definition: mkbundle.c:93
boost::shared_ptr< MathFunction > ct
Definition: vm_test.cpp:34
struct xray ray
Definition: raytrace.h:234
int rt_gen_frustum(struct xrays *rays, const struct xray *center_ray, const vect_t a_vec, const vect_t b_vec, const fastf_t a_theta, const fastf_t b_theta, const fastf_t a_num, const fastf_t b_num)
Definition: mkbundle.c:217
int rt_gen_conic(struct xrays *rays, const struct xray *center_ray, fastf_t theta, vect_t up_vector, int rays_per_radius)
Definition: mkbundle.c:158
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
uint32_t magic
Definition: raytrace.h:216