Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : Curve.cc
3 : : //
4 : : // Purpose :
5 : : //
6 : : // Special Notes :
7 : : //
8 : : // Creator : Xuechen Liu
9 : : //
10 : : // Creation Date : 08/02/96
11 : : //
12 : : // Owner : Malcolm J. Panthaki
13 : : //-------------------------------------------------------------------------
14 : :
15 : : // ********** BEGIN STANDARD INCLUDES **********
16 : : // ********** END STANDARD INCLUDES **********
17 : :
18 : : // ********** BEGIN CUBIT INCLUDES **********
19 : : #include "Curve.hpp"
20 : : #include "Point.hpp"
21 : : #include "GeometryQueryTool.hpp"
22 : :
23 : : #include "CastTo.hpp"
24 : : #include "CubitMessage.hpp"
25 : : // ********** END CUBIT INCLUDES **********
26 : :
27 : : // ********** BEGIN STATIC DECLARATIONS **********
28 : : // ********** END STATIC DECLARATIONS **********
29 : :
30 : : // ********** BEGIN PUBLIC FUNCTIONS **********
31 : :
32 : : //-------------------------------------------------------------------------
33 : : // Purpose : The default constructor. Does not do anything right now.
34 : : //
35 : : // Special Notes :
36 : : //
37 : : // Creator : Xuechen Liu
38 : : //
39 : : // Creation Date : 08/02/96
40 : : //-------------------------------------------------------------------------
41 : :
42 : 76260 : Curve::Curve()
43 : 38130 : {}
44 : :
45 : : //-------------------------------------------------------------------------
46 : : // Purpose : The destructor. Does not do anything right now.
47 : : //
48 : : // Special Notes :
49 : : //
50 : : // Creator : Raikanta Sahu
51 : : //
52 : : // Creation Date : 09/06/96
53 : : //-------------------------------------------------------------------------
54 : :
55 : 43946 : Curve::~Curve()
56 [ - + ]: 21973 : {}
57 : :
58 : 268 : CubitSense Curve::relative_sense(Curve *other_curve)
59 : : {
60 [ + - ][ + - ]: 268 : CubitVector center, junk, this_tangent, other_tangent;
[ + - ][ + - ]
61 : : double start, end;
62 : :
63 [ + - ][ + - ]: 804 : if (!get_param_range(start,end) ||
[ - + ]
64 [ + - ][ + - ]: 536 : !position_from_u(0.5*(start+end), center) ||
65 [ + - ][ + - ]: 804 : !closest_point(center, junk, &this_tangent) ||
[ - + ]
66 [ + - ]: 268 : !other_curve->closest_point(center, junk, &other_tangent))
67 : 0 : return CUBIT_UNKNOWN;
68 : :
69 [ + - ]: 268 : double dot = this_tangent % other_tangent;
70 [ + - ]: 268 : return dot == 0.0 ? CUBIT_UNKNOWN : dot > 0. ? CUBIT_FORWARD : CUBIT_REVERSED;
71 : : }
72 : :
73 : : //- When this is implemented in VirtualGeometryEngine it should be a pure vitual
74 : 0 : CubitStatus Curve::get_point_direction( CubitVector& , CubitVector& )
75 : : {
76 : 0 : return CUBIT_FAILURE;
77 : : }
78 : :
79 : : //- default implementation
80 : 0 : CubitStatus Curve::get_center_radius( CubitVector& c, double& r)
81 : : {
82 [ # # ][ # # ]: 0 : CubitVector start_pos, closest_pos;
83 [ # # ][ # # ]: 0 : if ( position_from_u(start_param(), start_pos) &&
[ # # ][ # # ]
[ # # ]
84 [ # # ]: 0 : closest_point(start_pos, closest_pos, 0, &c) )
85 : : {
86 [ # # ]: 0 : r = c.length();
87 [ # # ]: 0 : if (r > CUBIT_RESABS)
88 : : {
89 : 0 : r = 1.0 / r;
90 [ # # ]: 0 : c *= r * r;
91 [ # # ]: 0 : c += closest_pos;
92 : 0 : return CUBIT_SUCCESS;
93 : : }
94 : : }
95 : 0 : return CUBIT_FAILURE;
96 : : }
97 : :
98 : : //-------------------------------------------------------------------------
99 : : // Purpose : This function returns the point that is a distance
100 : : // arc length from the root_point.
101 : : //
102 : : // Special Notes : If the root point is on a periodic curve, it may
103 : : // accidentaly get the wrong parameter. There is
104 : : // a special test here to make sure root point does
105 : : // not get set as the end parameter...
106 : : // If root point is at the end, we will assert later on..
107 : : //
108 : : // Creator : David White
109 : : //
110 : : // Creation Date : 03/24/97
111 : : //-------------------------------------------------------------------------
112 : 0 : CubitStatus Curve::point_from_arc_length ( const CubitVector &root_point,
113 : : double const arc_length,
114 : : CubitVector& new_point )
115 : : {
116 : : // Get the parameter value of the root point
117 : 0 : double root_param = u_from_position( root_point );
118 : 0 : return point_from_arc_length(root_param, arc_length, new_point);
119 : : }
120 : :
121 : : //-------------------------------------------------------------------------
122 : : // Purpose : This function returns the point that is a distance
123 : : // arc length from the point corresponding to root_param
124 : : //
125 : : // Special Notes : The original point_from_arc_length was split up
126 : : // to allow the starting parameter to be specified directly.
127 : : // This helps with periodic curves, where the start_param of the
128 : : // curve can be passed in so we're sure its starting from the
129 : : // start vertex.
130 : : //
131 : : // Creator : David White (modified by Ved Vyas)
132 : : //
133 : : // Creation Date : 5/21/2006
134 : : //-------------------------------------------------------------------------
135 : :
136 : 0 : CubitStatus Curve::point_from_arc_length( double root_param,
137 : : const double arc_length,
138 : : CubitVector &new_point )
139 : : {
140 [ # # ]: 0 : double low_param = start_param();
141 [ # # ]: 0 : double high_param = end_param();
142 : :
143 [ # # ]: 0 : if (high_param < low_param)
144 : : {
145 : 0 : double temp = high_param;
146 : 0 : high_param = low_param;
147 : 0 : low_param = temp;
148 : : }
149 : :
150 : : // Comment: The way we handle points not on the bounded curve is
151 : : // different for periodic and non-periodic curves!
152 : : // Periodic curves leave the parameter off of the curve,
153 : : // while non-periodic curves move the point to the closest
154 : : // endpoint. Just an observation!
155 : :
156 : :
157 : : // Adjust the parameter for periodic curves
158 : : double periodic_param;
159 : :
160 [ # # ][ # # ]: 0 : if ( is_periodic( periodic_param ))
161 : : {
162 [ # # ]: 0 : while (root_param < low_param)
163 : 0 : root_param += periodic_param;
164 [ # # ]: 0 : while (root_param > high_param)
165 : 0 : root_param -= periodic_param;
166 : : // If you're moving in the positive direction and
167 : : // you're almost at the start point...
168 [ # # ][ # # ]: 0 : if (fabs( this->end_param() - root_param ) <= CUBIT_RESABS &&
[ # # ][ # # ]
169 : : arc_length > 0.0 )
170 : : {
171 : : //the root param should be switched with the start param.
172 [ # # ]: 0 : root_param = this->start_param();
173 : : }
174 : : // If you're moving in the negative direction and
175 : : // you're almost at the end point...
176 [ # # ][ # # ]: 0 : else if (fabs( this->start_param() - root_param ) <= CUBIT_RESABS &&
[ # # ][ # # ]
177 : : arc_length < 0.0 )
178 : : {
179 [ # # ]: 0 : root_param = this->end_param();
180 : : }
181 : : }
182 [ # # ]: 0 : else if ( root_param < (low_param + CUBIT_RESABS) )
183 : 0 : root_param = low_param;
184 [ # # ]: 0 : else if ( root_param > (high_param - CUBIT_RESABS) )
185 : 0 : root_param = high_param;
186 : :
187 : : // Get the parameter value of the new point
188 : : double new_param = this->u_from_arc_length( root_param,
189 [ # # ]: 0 : arc_length );
190 : :
191 : : // Now get the coordinates (in world space) representing this parameter
192 : : // value
193 [ # # ]: 0 : return this->position_from_u(new_param, new_point);
194 : : }
195 : :
196 : : //-------------------------------------------------------------------------
197 : : // Purpose : Find the closest point on a BOUNDED curve.
198 : : //
199 : : // Creator : Jason Kraftcheck
200 : : //
201 : : // Creation Date : 07/17/98
202 : : //-------------------------------------------------------------------------
203 : 20403 : CubitStatus Curve::closest_point_trimmed( CubitVector const& from_pt,
204 : : CubitVector& result )
205 : : {
206 : : // Get the untrimmed point
207 : : double param;
208 [ + - ][ + + ]: 20403 : if ( !closest_point(from_pt, result, NULL, NULL, ¶m) )
209 : 1723 : return CUBIT_FAILURE;
210 : :
211 : 18680 : double param_range = 0.0;
212 : : double period, start_param, end_param;
213 : :
214 : : // Get whether periodic
215 [ + - ]: 18680 : CubitBoolean is_per = this->is_periodic(period);
216 : : // Get the parameter range
217 [ + - ]: 18680 : get_param_range( start_param, end_param );
218 : :
219 : : // Make sure the start_param is lower than end_param.
220 [ - + ]: 18680 : if (start_param > end_param)
221 : : {
222 : : // use param_range as temp
223 : 0 : param_range = start_param;
224 : 0 : start_param = end_param;
225 : 0 : end_param = param_range;
226 : : }
227 : 18680 : param_range = end_param - start_param;
228 : :
229 : : // If the Curve does not loop onto itself...
230 [ + + ][ - + ]: 18680 : if( is_per == CUBIT_FALSE ||
231 : 280 : param_range < period)
232 : : {
233 : : // If not within parameter range, return
234 : : // the the closest endpoint
235 [ + - ][ + - ]: 18400 : CubitVector start, end;
236 [ + - ]: 18400 : position_from_u( start_param, start );
237 [ + - ]: 18400 : position_from_u( end_param, end );
238 : :
239 [ + - ][ - + ]: 18400 : if( (param < start_param) || (param > end_param) )
240 : : {
241 [ # # ][ # # ]: 0 : result = ( (start - result).length_squared() <
[ # # ]
242 [ # # ][ # # ]: 0 : (end - result).length_squared() ) ? start : end ;
[ # # ]
243 : : }
244 : : else
245 : : {
246 [ + - ][ + - ]: 18400 : double tmp_dist_sq = (from_pt - result).length_squared();
247 [ + - ][ + - ]: 18400 : if( (start-from_pt).length_squared() < tmp_dist_sq )
[ - + ]
248 [ # # ]: 0 : result = start;
249 [ + - ][ + - ]: 18400 : else if( (end-from_pt).length_squared() < tmp_dist_sq )
[ - + ]
250 [ # # ]: 18400 : result = end;
251 : : }
252 : : }
253 : :
254 : :
255 : 20403 : return CUBIT_SUCCESS;
256 : : }
257 : :
258 : : //-------------------------------------------------------------------------
259 : : // Purpose : Check for discontinuity in the tangents of a curve
260 : : //
261 : : // Special Notes :
262 : : //
263 : : // Creator : Jason Kraftcheck
264 : : //
265 : : // Creation Date : 05/01/00
266 : : //-------------------------------------------------------------------------
267 : 0 : CubitBoolean Curve::G1_discontinuous( double u,
268 : : CubitVector* minus_tangent_r, CubitVector* plus_tangent_r )
269 : : {
270 : : double start_param, end_param;
271 [ # # ][ # # ]: 0 : if( ! get_param_range( start_param, end_param ) ) return CUBIT_FALSE;
272 : : //if the curve is not parametric, just return false.
273 [ # # ]: 0 : if( start_param > end_param )
274 : : {
275 : 0 : double tmp = start_param;
276 : 0 : start_param = end_param;
277 : 0 : end_param = tmp;
278 : : }
279 : :
280 : 0 : double u_minus = (2 * CUBIT_RESABS);
281 : 0 : double u_plus = u_minus;
282 : :
283 : : //can't be C1 discontinous at an end point!
284 [ # # ][ # # ]: 0 : if( ((u - u_minus) < start_param) || ((u + u_plus) > end_param) )
285 : 0 : return CUBIT_FALSE;
286 : :
287 [ # # ]: 0 : CubitVector position;
288 [ # # ]: 0 : position_from_u( u, position );
289 : 0 : const double res_abs_sqr = CUBIT_RESABS * CUBIT_RESABS;
290 : :
291 [ # # ][ # # ]: 0 : CubitVector minus_position, minus_tangent;
292 [ # # ]: 0 : position_from_u( u - u_minus, minus_position );
293 [ # # ]: 0 : double u_minus2 = u_from_position( minus_position );
294 [ # # ][ # # ]: 0 : minus_tangent = position - minus_position;
295 : :
296 [ # # ][ # # ]: 0 : while( ((u - u_minus2) > (u - CUBIT_RESABS)) ||
[ # # ]
297 [ # # ]: 0 : (minus_tangent.length_squared() < res_abs_sqr) )
298 : : {
299 : 0 : u_minus *= 10.;
300 : : //can't be C1 discontinous at an end point!
301 [ # # ]: 0 : if( (u - u_minus) < start_param ) return CUBIT_FALSE;
302 [ # # ]: 0 : position_from_u( u - u_minus, minus_position );
303 [ # # ]: 0 : u_minus2 = u_from_position( minus_position );
304 [ # # ][ # # ]: 0 : minus_tangent = position - minus_position;
305 : : }
306 : :
307 [ # # ][ # # ]: 0 : CubitVector plus_position, plus_tangent;
308 [ # # ]: 0 : position_from_u( u + u_plus, plus_position );
309 [ # # ]: 0 : double u_plus2 = u_from_position( plus_position );
310 [ # # ][ # # ]: 0 : plus_tangent = plus_position - position;
311 : :
312 [ # # ][ # # ]: 0 : while( ((u + u_plus2) < (u + CUBIT_RESABS)) ||
[ # # ]
313 [ # # ][ # # ]: 0 : ((position - plus_position).length_squared() < res_abs_sqr) )
[ # # ][ # # ]
314 : : {
315 : 0 : u_plus *= 10.;
316 : : //can't be C1 discontinous at an end point!
317 [ # # ]: 0 : if( (u + u_plus) > end_param ) return CUBIT_FALSE;
318 [ # # ]: 0 : position_from_u( u + u_plus, plus_position );
319 [ # # ]: 0 : u_plus2 = u_from_position( plus_position );
320 [ # # ][ # # ]: 0 : plus_tangent = plus_position - position;
321 : : }
322 : :
323 [ # # ]: 0 : plus_tangent.normalize();
324 [ # # ]: 0 : minus_tangent.normalize();
325 [ # # ][ # # ]: 0 : if( (plus_tangent * minus_tangent).length_squared() > (2 * res_abs_sqr) )
[ # # ]
326 : : {
327 [ # # ][ # # ]: 0 : if( plus_tangent_r ) *plus_tangent_r = plus_tangent;
328 [ # # ][ # # ]: 0 : if( minus_tangent_r ) * minus_tangent_r = minus_tangent;
329 : 0 : return CUBIT_TRUE;
330 : : }
331 : :
332 : 0 : return CUBIT_FALSE;
333 [ + - ][ + - ]: 6540 : }
334 : :
335 : : // ********** END PUBLIC FUNCTIONS **********
336 : :
337 : : // ********** BEGIN PROTECTED FUNCTIONS **********
338 : : // ********** END PROTECTED FUNCTIONS **********
339 : :
340 : : // ********** BEGIN PRIVATE FUNCTIONS **********
341 : : // ********** END PRIVATE FUNCTIONS **********
342 : :
343 : : // ********** BEGIN HELPER CLASSES **********
344 : : // ********** END HELPER CLASSES **********
345 : :
346 : : // ********** BEGIN EXTERN FUNCTIONS **********
347 : : // ********** END EXTERN FUNCTIONS **********
348 : :
349 : : // ********** BEGIN STATIC FUNCTIONS **********
350 : : // ********** END STATIC FUNCTIONS **********
351 : :
|