int intersect(L(A, B), C(O, r), point & res1, point & res2) { double h = abs(O - closest_point(A, B, O)); if(r < h - EPS) return 0; point H = proj(O - A, B - A) + A, v = normalize((B - A), sqrt(r*r - h*h)); res1 = H + v; res2 = H - v; if(abs(v) < EPS) return 1; return 2; }
Point LineSegment::closest_point (const Point & p) const { Point closest_p; closest_point(p, true, closest_p); return closest_p; }
//=========================================================================== //Function Name: evaluate_position // //Member Type: PUBLIC //Description: evaluate the facet edge at a position // eval_tangent is NULL if tangent not needed //=========================================================================== CubitStatus CubitFacetEdge::evaluate_position( const CubitVector &start_position, CubitVector *eval_point, CubitVector *eval_tangent) { CubitStatus stat = CUBIT_SUCCESS; // find the adjacent facet CubitFacet *facet_ptr = this->adj_facet( 0 ); // If there is none or this is a linear representation - // then project to the linear edge if (!facet_ptr || facet_ptr->eval_order() == 0 || facet_ptr->is_flat()) { if (eval_point) { closest_point(start_position, *eval_point); } if (eval_tangent) { *eval_tangent = point(1)->coordinates() - point(0)->coordinates(); (*eval_tangent).normalize(); } } else { int vert0 = facet_ptr->point_index( point(0) ); int vert1 = facet_ptr->point_index( point(1) ); CubitVector pt_on_plane, close_point; CubitVector start = start_position; double dist_to_plane; CubitBoolean outside_facet; FacetEvalTool::project_to_facet_plane( facet_ptr, start, pt_on_plane, dist_to_plane ); stat = FacetEvalTool::project_to_facetedge( facet_ptr, vert0, vert1, start, pt_on_plane, close_point, outside_facet ); if (eval_point) { *eval_point = close_point; } if (eval_tangent) { CubitVector edvec = point(1)->coordinates() - point(0)->coordinates(); edvec.normalize(); CubitVector areacoord; FacetEvalTool::facet_area_coordinate( facet_ptr, close_point, areacoord ); FacetEvalTool::eval_facet_normal(facet_ptr, areacoord, *eval_tangent); CubitVector cross = edvec * *eval_tangent; *eval_tangent = *eval_tangent * cross; (*eval_tangent).normalize(); } } return CUBIT_SUCCESS; }
CubitStatus OCCSurface::closest_point_uv_guess( CubitVector const& location, double& , double& , CubitVector* closest_location, CubitVector* unit_normal ) { // don't use u and v guesses return closest_point(location, closest_location, unit_normal); }
//------------------------------------------------------------------------- // Purpose : This function tests the passed in position to see if // is on the underlying surface. // //------------------------------------------------------------------------- CubitBoolean OCCSurface::is_position_on( CubitVector &test_position ) { CubitVector new_point; CubitStatus stat = closest_point(test_position, &new_point, NULL,NULL,NULL); if ( !stat ) return CUBIT_FALSE; CubitVector result_vec = test_position - new_point; if ( result_vec.length_squared() < GEOMETRY_RESABS ) return CUBIT_TRUE; return CUBIT_FALSE; }
//------------------------------------------------------------------------- // Purpose : make arbitrary parameterization // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 07/06/98 //------------------------------------------------------------------------- void ParamCubitPlane::make_parameterization() { //Choose the zero-point for the parameterization //as close to the origin as possible. // p_.set( 0.0, 0.0, 0.0); // move_to_plane( p_ ); is_plane_valid_ = CUBIT_TRUE; const CubitVector temp_p(0.0, 0.0, 0.0); CubitStatus s = closest_point( temp_p, p_ ); assert( s == CUBIT_SUCCESS ); CubitVector n = normal(); CubitVector p1; p1 = p_; double x = fabs( n.x() ); double y = fabs( n.y() ); double z = fabs( n.z() ); //Choose a direction from the zero point (p_) for //the second point as the direction of the smallest //component of the normal. The third point defining //the plane will be defined by the cross product of //the vector from the zero_point to this point and //the normal vector of the plane. if( (x <= y) && (x <= z) ) { p1.x( p1.x() + 1 ); } else if( (y <= x) && (y <= z) ) { p1.y( p1.y() + 1 ); } else { p1.z( p1.z() + 1 ); } move_to_plane( p1 ); s_ = p1 - p_; t_ = -(s_ * n); n_ = s_ * t_; double n_len = n_.length(); if( 1000 * CUBIT_DBL_MIN > n_len ) n_epsilon_ = CUBIT_DBL_MIN; else n_epsilon_ = n_len / 1000; is_plane_valid_= CUBIT_TRUE; }
//------------------------------------------------------------------------- // Purpose : This functions computes the point on the surface that is // closest to the input location and then calculates the // magnitudes of the principal curvatures at this (possibly, // new) point on the surface. // // Special Notes : // //------------------------------------------------------------------------- CubitStatus SphereEvaluator::principal_curvatures( CubitVector const& location, double& curvature_1, double& curvature_2, CubitVector* closest_location ) { curvature_1 = curvature_2 = 1.0 / mEvalData.radius; if ( closest_location ) { closest_point( location, closest_location ); } return CUBIT_SUCCESS; }
static Boolean closest_in_tween(Poly **pp, LLpoint **pl, long *pdist, int x, int y, int end_mode) /* Return closest point in selectable polygon */ { Poly *p1, *p2; LLpoint *lp1, *lp2; long d1, d2; if (!get_p1_p2(&p1,&p2)) return(FALSE); lp1 = (end_mode != TWEEN_END ? closest_point(p1, x, y, &d1) : NULL); lp2 = (end_mode != TWEEN_START ? closest_point(p2, x, y, &d2) : NULL); if (lp1 == NULL) goto GOT_D2; else if (lp2 == NULL) goto GOT_D1; else { if (d1 < d2) goto GOT_D1; else goto GOT_D2; } GOT_D1: *pp = p1; *pl = lp1; *pdist = d1; goto OUT; GOT_D2: *pp = p2; *pl = lp2; *pdist = d2; goto OUT; OUT: return(TRUE); }
int main(int argc,char **argv) { if(argc < 3) { fprintf(stderr,"No enough parameter.\n"); exit(1); } uint32_t size = argc - 1; int32_t *array = (int32_t*)malloc(sizeof(int32_t) * size); int i; for(i = 0; i < size; ++i) { array[i] = atoi(argv[i + 1]); fprintf(stdout,"%d ",array[i]); } fprintf(stdout,"\n"); fprintf(stdout,"%d\n",closest_point(array,array+size)); free(array); return 0; }
CubitStatus Surface::closest_points(DLIList<CubitVector *> &location_list, DLIList<CubitVector *> *closest_location_list, DLIList<CubitVector *> *unit_normal_list, DLIList<CubitVector *> *curvature1_list, DLIList<CubitVector *> *curvature2_list) { CubitVector *curvature1, *curvature2; CubitVector *unit_normal; CubitVector *closest_location; CubitVector *location; CubitStatus stat; location_list.reset(); if (closest_location_list) closest_location_list->reset(); if (unit_normal_list) unit_normal_list->reset(); if (curvature1_list) curvature1_list->reset(); if (curvature2_list) curvature2_list->reset(); for (int i=0; i<location_list.size(); i++) { location = location_list.get_and_step(); if (closest_location_list == NULL) closest_location = NULL; else closest_location = closest_location_list->get_and_step(); if (unit_normal_list == NULL) unit_normal = NULL; else unit_normal = unit_normal_list->get_and_step(); if (curvature1_list == NULL) curvature1 = NULL; else curvature1 = curvature1_list->get_and_step(); if (curvature2_list == NULL) curvature2 = NULL; else curvature2 = curvature2_list->get_and_step(); stat = closest_point( *location, closest_location, unit_normal, curvature1, curvature2 ); if (stat != CUBIT_SUCCESS) return stat; } return CUBIT_SUCCESS; }
double line_segment_distance(L(a,b), L(c,d)) { double x = INFINITY; if (abs(a - b) < EPS && abs(c - d) < EPS) x = abs(a - c); else if (abs(a - b) < EPS) x = abs(a - closest_point(c, d, a, true)); else if (abs(c - d) < EPS) x = abs(c - closest_point(a, b, c, true)); else if ((ccw(a, b, c) < 0) != (ccw(a, b, d) < 0) && (ccw(c, d, a) < 0) != (ccw(c, d, b) < 0)) x = 0; else { x = min(x, abs(a - closest_point(c,d, a, true))); x = min(x, abs(b - closest_point(c,d, b, true))); x = min(x, abs(c - closest_point(a,b, c, true))); x = min(x, abs(d - closest_point(a,b, d, true))); } return x; }
int main() { point p, q; assert(line_intersection(-1, 1, 0, 1, 1, -3, &p) == 0); assert(EQP(p, point(1.5, 1.5))); assert(line_intersection(point(0, 0), point(1, 1), point(0, 4), point(4, 0), &p) == 0); assert(EQP(p, point(2, 2))); { #define test(a, b, c, d, e, f, g, h) seg_intersection( \ point(a, b), point(c, d), point(e, f), point(g, h), &p, &q) // Intersection is a point. assert(0 == test(-4, 0, 4, 0, 0, -4, 0, 4) && EQP(p, point(0, 0))); assert(0 == test(0, 0, 10, 10, 2, 2, 16, 4) && EQP(p, point(2, 2))); assert(0 == test(-2, 2, -2, -2, -2, 0, 0, 0) && EQP(p, point(-2, 0))); assert(0 == test(0, 4, 4, 4, 4, 0, 4, 8) && EQP(p, point(4, 4))); // Intersection is a segment. assert(1 == test(10, 10, 0, 0, 2, 2, 6, 6)); assert(EQP(p, point(2, 2)) && EQP(q, point(6, 6))); assert(1 == test(6, 8, 14, -2, 14, -2, 6, 8)); assert(EQP(p, point(6, 8)) && EQP(q, point(14, -2))); // No intersection. assert(-1 == test(6, 8, 8, 10, 12, 12, 4, 4)); assert(-1 == test(-4, 2, -8, 8, 0, 0, -4, 6)); assert(-1 == test(4, 4, 4, 6, 0, 2, 0, 0)); assert(-1 == test(4, 4, 6, 4, 0, 2, 0, 0)); assert(-1 == test(-2, -2, 4, 4, 10, 10, 6, 6)); assert(-1 == test(0, 0, 2, 2, 4, 0, 1, 4)); assert(-1 == test(2, 2, 2, 8, 4, 4, 6, 4)); assert(-1 == test(4, 2, 4, 4, 0, 8, 10, 0)); } assert(EQP(point(2.5, 2.5), closest_point(-1, -1, 5, point(0, 0)))); assert(EQP(point(3, 0), closest_point(1, 0, -3, point(0, 0)))); assert(EQP(point(0, 3), closest_point(0, 1, -3, point(0, 0)))); assert(EQP(point(3, 0), closest_point(point(3, 0), point(3, 3), point(0, 0)))); assert(EQP(point(2, -1), closest_point(point(2, -1), point(4, -1), point(0, 0)))); assert(EQP(point(4, -1), closest_point(point(2, -1), point(4, -1), point(5, 0)))); return 0; }
//------------------------------------------------------------------------- // Purpose : Project a given XYZ position to a surface and return // the UV and XYZ locations on the surface. //------------------------------------------------------------------------- CubitStatus SphereEvaluator::u_v_from_position ( CubitVector const& location, double& u, double& v, CubitVector* closest_location ) const { CubitTransformMatrix inverse_Tmatrix = mTmatrix; inverse_Tmatrix.inverse(); CubitVector transformed_pt = inverse_Tmatrix * location; CubitVector dir( transformed_pt ); dir.normalize(); v = acos( dir.z() ); if ( v < GEOMETRY_RESABS ) { u = 0.0; } else { dir.set( dir.x(), dir.y(), 0.0 ); dir.normalize(); u = acos( dir.x() ); if ( dir.y() < 0.0 ) { u = 2*CUBIT_PI - u; } while ( u < 0.0 ) u += 2*CUBIT_PI; while ( u >= 2*CUBIT_PI ) u -= 2*CUBIT_PI; } if ( closest_location ) closest_point( location, closest_location ); return CUBIT_SUCCESS; }
//------------------------------------------------------------------------- // Purpose : closest point // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 07/06/98 //------------------------------------------------------------------------- CubitStatus ParamCubitPlane::move_to_plane( CubitVector& position ) const { const CubitVector v = position; CubitStatus s = closest_point( v, position ); return s; }
CubitStatus FacetSurface::get_point_normal( CubitVector& location, CubitVector& normal ) { return closest_point( location, NULL, &normal ); }
double distance(const Vector2& point, const Segment& segment) { Vector2 proj = closest_point(point, segment); return (proj - point).norm2(); }
CubitStatus OCCSurface::get_point_normal( CubitVector& location, CubitVector& normal ) { return closest_point( bounding_box().center(), &location, &normal ); }
double dist(const caliper &other) { point a(pt.first,pt.second), b = a + exp(point(0,angle)) * 10.0, c(other.pt.first, other.pt.second); return abs(c - closest_point(a, b, c)); } };
template<class T> T Triangle<Vector<T,2>>:: distance(const TV& location) const { return magnitude(location-closest_point(location).x); }
bool LineSegment::closest_normal_point (const Point & p, Point & closest_p) const { return closest_point(p, false, closest_p); }
bool LineSegment::contains_point (const Point & p) const { Point closest_p; return closest_point(p, false, closest_p) && closest_p == p; }
//Closest point from c on segment ab pt closest_point_seg(pt a, pt b, pt c){ pt close = closest_point(a, b, c); if(in_box(a, b, close)) return close; return dist(a, c) < dist(b, c) ? a : b; }
//! \brief Tells wheter there is an intersection between a circle and a axis-aligned rectangle. //! \retval `true` if there is an intersection, `false` else. inline bool has_intersection( circle const& c, aabr const& r ) { real2 closest_point( CLAMP(r.left(),c.center.x,r.right()), CLAMP(r.bottom(),c.center.x,r.top()) ); return dist2sq(c.center, closest_point) <= SQ(c.radius); }