BRL-CAD
clip.c
Go to the documentation of this file.
1 /* C L I P . 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 
21 #include "common.h"
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include <string.h>
26 
27 #include "bu/log.h"
28 #include "bu/str.h"
29 #include "vmath.h"
30 #include "bn/adc.h"
31 #include "bn/clip.h"
32 
33 /* XXX need to test more thoroughly
34  #define ANGLE_EPSILON 0.0001
35  #define CLIP_DISTANCE 1000000000.0
36 */
37 #define EPSILON 0.0001
38 #define CLIP_DISTANCE 100000000.0
39 
40 static int
41 clip_code(fastf_t x, fastf_t y, fastf_t clip_min, fastf_t clip_max)
42 {
43  int cval;
44 
45  cval = 0;
46  if (x < clip_min)
47  cval |= 01;
48  else if (x > clip_max)
49  cval |= 02;
50 
51  if (y < clip_min)
52  cval |= 04;
53  else if (y > clip_max)
54  cval |= 010;
55 
56  return cval;
57 }
58 
59 /* clip a 2-D integer line seg against the size of the display */
60 int
61 bn_lseg_clip(fastf_t *xp1, fastf_t *yp1, fastf_t *xp2, fastf_t *yp2, fastf_t clip_min, fastf_t clip_max)
62 {
63  char code1, code2;
64 
65  code1 = clip_code(*xp1, *yp1, clip_min, clip_max);
66  code2 = clip_code(*xp2, *yp2, clip_min, clip_max);
67 
68  while (code1 || code2) {
69  if (code1 & code2)
70  return 1; /* No part is visible */
71 
72  /* SWAP codes, X's, and Y's */
73  if (code1 == 0) {
74  char ctemp;
75  fastf_t temp;
76 
77  ctemp = code1;
78  code1 = code2;
79  code2 = ctemp;
80 
81  temp = *xp1;
82  *xp1 = *xp2;
83  *xp2 = temp;
84 
85  temp = *yp1;
86  *yp1 = *yp2;
87  *yp2 = temp;
88  }
89 
90  if (code1 & 01) {
91  /* Push toward left edge */
92  *yp1 = *yp1 + (*yp2-*yp1)*(clip_min-*xp1)/(*xp2-*xp1);
93  *xp1 = clip_min;
94  } else if (code1 & 02) {
95  /* Push toward right edge */
96  *yp1 = *yp1 + (*yp2-*yp1)*(clip_max-*xp1)/(*xp2-*xp1);
97  *xp1 = clip_max;
98  } else if (code1 & 04) {
99  /* Push toward bottom edge */
100  *xp1 = *xp1 + (*xp2-*xp1)*(clip_min-*yp1)/(*yp2-*yp1);
101  *yp1 = clip_min;
102  } else if (code1 & 010) {
103  /* Push toward top edge */
104  *xp1 = *xp1 + (*xp2-*xp1)*(clip_max-*yp1)/(*yp2-*yp1);
105  *yp1 = clip_max;
106  }
107 
108  code1 = clip_code(*xp1, *yp1, clip_min, clip_max);
109  }
110 
111  return 0;
112 }
113 
114 /*
115  * Clip a ray against a rectangular parallelepiped (RPP)
116  * that has faces parallel to the coordinate planes (a clipping RPP).
117  * The RPP is defined by a minimum point and a maximum point.
118  *
119  * Returns -
120  * 0 if ray does not hit RPP,
121  * !0 if ray hits RPP.
122  *
123  * Implicit Return -
124  * if !0 was returned, "a" and "b" have been clipped to the RPP.
125  */
126 int
127 bn_ray_vclip(vect_t a, vect_t b, fastf_t *min, fastf_t *max)
128 {
129  static vect_t diff;
130  static double sv;
131  static double st;
132  static double mindist, maxdist;
133  fastf_t *pt = &a[0];
134  fastf_t *dir = &diff[0];
135  int i;
136 
137  mindist = -CLIP_DISTANCE;
138  maxdist = CLIP_DISTANCE;
139  VSUB2(diff, b, a);
140 
141  for (i = 0; i < 3; i++, pt++, dir++, max++, min++) {
142  if (*dir < -EPSILON) {
143  sv = (*min - *pt) / *dir;
144  if (sv < 0.0)
145  return 0; /* MISS */
146 
147  st = (*max - *pt) / *dir;
148  V_MAX(mindist, st);
149  V_MIN(maxdist, sv);
150 
151  } else if (*dir > EPSILON) {
152  st = (*max - *pt) / *dir;
153  if (st < 0.0)
154  return 0; /* MISS */
155 
156  sv = (*min - *pt) / *dir;
157  V_MAX(mindist, sv);
158  V_MIN(maxdist, st);
159  } else {
160  /*
161  * If direction component along this axis is NEAR 0,
162  * (i.e., this ray is aligned with this axis),
163  * merely check against the boundaries.
164  */
165  if ((*min > *pt) || (*max < *pt))
166  return 0; /* MISS */;
167  }
168  }
169  if (mindist >= maxdist)
170  return 0; /* MISS */
171 
172  if (mindist > 1 || maxdist < 0)
173  return 0; /* MISS */
174 
175  if (mindist <= 0 && maxdist >= 1)
176  return 1; /* HIT, no clipping needed */
177 
178  /* Don't grow one end of a contained segment */
179  V_MAX(mindist, 0);
180  V_MIN(maxdist, 1);
181 
182  /* Compute actual intercept points */
183  VJOIN1(b, a, maxdist, diff); /* b must go first */
184  VJOIN1(a, a, mindist, diff);
185  return 1; /* HIT */
186 }
187 
188 
189 /* TODO - need a proper place for these... */
190 
191 void
192 adc_model_to_adc_view(struct bview_adc_state *adcs, mat_t model2view, fastf_t amax)
193 {
194  MAT4X3PNT(adcs->pos_view, model2view, adcs->pos_model);
195  adcs->dv_x = adcs->pos_view[X] * amax;
196  adcs->dv_y = adcs->pos_view[Y] * amax;
197 }
198 
199 
200 void
201 adc_grid_to_adc_view(struct bview_adc_state *adcs, mat_t model2view, fastf_t amax)
202 {
203  point_t model_pt;
204  point_t view_pt;
205 
206  VSETALL(model_pt, 0.0);
207  MAT4X3PNT(view_pt, model2view, model_pt);
208  VADD2(adcs->pos_view, view_pt, adcs->pos_grid);
209  adcs->dv_x = adcs->pos_view[X] * amax;
210  adcs->dv_y = adcs->pos_view[Y] * amax;
211 }
212 
213 
214 void
215 adc_view_to_adc_grid(struct bview_adc_state *adcs, mat_t model2view)
216 {
217  point_t model_pt;
218  point_t view_pt;
219 
220  VSETALL(model_pt, 0.0);
221  MAT4X3PNT(view_pt, model2view, model_pt);
222  VSUB2(adcs->pos_grid, adcs->pos_view, view_pt);
223 }
224 
225 /* From include/dm.h */
226 #define INV_GED 0.00048828125
227 
228 void
229 adc_reset(struct bview_adc_state *adcs, mat_t view2model, mat_t model2view)
230 {
231  adcs->dv_x = adcs->dv_y = 0;
232  adcs->dv_a1 = adcs->dv_a2 = 0;
233  adcs->dv_dist = 0;
234 
235  VSETALL(adcs->pos_view, 0.0);
236  MAT4X3PNT(adcs->pos_model, view2model, adcs->pos_view);
237  adcs->dst = (adcs->dv_dist * INV_GED + 1.0) * M_SQRT1_2;
238  adcs->a1 = adcs->a2 = 45.0;
239  adc_view_to_adc_grid(adcs, model2view);
240 
241  VSETALL(adcs->anchor_pt_a1, 0.0);
242  VSETALL(adcs->anchor_pt_a2, 0.0);
243  VSETALL(adcs->anchor_pt_dst, 0.0);
244 
245  adcs->anchor_pos = 0;
246  adcs->anchor_a1 = 0;
247  adcs->anchor_a2 = 0;
248  adcs->anchor_dst = 0;
249 }
250 
251 
252 
253 /*
254  * Local Variables:
255  * mode: C
256  * tab-width: 8
257  * indent-tabs-mode: t
258  * c-file-style: "stroustrup"
259  * End:
260  * ex: shiftwidth=4 tabstop=8
261  */
int anchor_a1
Definition: bview.h:67
void adc_model_to_adc_view(struct bview_adc_state *adcs, mat_t model2view, fastf_t amax)
Definition: clip.c:192
fastf_t a2
Definition: bview.h:64
#define VSETALL(a, s)
Definition: color.c:54
#define st
void adc_grid_to_adc_view(struct bview_adc_state *adcs, mat_t model2view, fastf_t amax)
Definition: clip.c:201
Header file for the BRL-CAD common definitions.
int dv_dist
Definition: bview.h:59
int anchor_pos
Definition: bview.h:66
fastf_t pos_grid[3]
Definition: bview.h:62
fastf_t a1
Definition: bview.h:63
Definition: color.c:49
fastf_t anchor_pt_a1[3]
Definition: bview.h:70
fastf_t anchor_pt_dst[3]
Definition: bview.h:72
fastf_t dst
Definition: bview.h:65
int bn_lseg_clip(fastf_t *xp1, fastf_t *yp1, fastf_t *xp2, fastf_t *yp2, fastf_t clip_min, fastf_t clip_max)
Clipping functions.
Definition: clip.c:61
int bn_ray_vclip(vect_t a, vect_t b, fastf_t *min, fastf_t *max)
Clip a ray against a rectangular parallelepiped (RPP) that has faces parallel to the coordinate plane...
Definition: clip.c:127
fastf_t anchor_pt_a2[3]
Definition: bview.h:71
fastf_t pos_view[3]
Definition: bview.h:61
#define CLIP_DISTANCE
Definition: clip.c:38
#define INV_GED
Definition: clip.c:226
fastf_t pos_model[3]
Definition: bview.h:60
basis_s * b
Definition: chull3d.cpp:151
#define EPSILON
Definition: clip.c:37
int anchor_dst
Definition: bview.h:69
#define M_SQRT1_2
Definition: fft.h:38
double fastf_t
Definition: defines.h:300
void adc_reset(struct bview_adc_state *adcs, mat_t view2model, mat_t model2view)
Definition: clip.c:229
void adc_view_to_adc_grid(struct bview_adc_state *adcs, mat_t model2view)
Definition: clip.c:215
int anchor_a2
Definition: bview.h:68
Definition: color.c:50