Exemple #1
0
/**
 * This method returns the m_vector index of the first point of the threshold edge that is
 * intersected by the specified segment, otherwise the method returns a value one higher than
 * the maximum m_vector index (i.e., m_vector.size())
 *
 * If the segment does intersect a threshold edge the intersection
 * point is returned by the _crs_pt parameter.
 *
 * NB: the threshold MUST be convex and have vertices oriented
 *     counterclockwise; this code does not verify these conditions.
 *
 * @param _seg the segment
 * @param _crs_pt the intersection point
 * @return the index of the first point of the edge that is intersected
 *         if no intersection is found the index of the last point of
 *         the last edge is returned
 * @throw CException should any of the following occur:
 *        1. segment is really a single point.
 */
unsigned long CThreshold::crossed_by(seg _seg, pt& _crs_pt) {
    unsigned long i = 0; // for loop index

    seg edge; // threshold edge
    pt i1, i2; // intersection points

    _crs_pt.x = 0.0;
    _crs_pt.y = 0.0;

	if (pts_equal(_seg.p1, _seg.p2)) {
		throw CException("Error! Segment is really a single point.");
	}

	// process each threshold edge
	for (i = 0; i < m_vertex.size()-1; i++) {
		edge.p1.x = m_vertex[i].x;
		edge.p1.y = m_vertex[i].y;
		edge.p2.x = m_vertex[i+1].x;
		edge.p2.y = m_vertex[i+1].y;

		if (seg_intersection(edge, _seg, i1, i2)) {
			// there is a valid intersection point
			_crs_pt.x = i1.x;
			_crs_pt.y = i1.y;

			if ((THRESHOLD_TYPE_BZREVERSAL == m_vertex[i].type && (THRESHOLD_TYPE_BZREVERSAL & m_vertex[i+1].type))
				||
				((THRESHOLD_TYPE_BZREVERSAL & m_vertex[i].type) && THRESHOLD_TYPE_BZREVERSAL == m_vertex[i+1].type)
				||
				((THRESHOLD_TYPE_BZREVERSAL & m_vertex[i].type) && (THRESHOLD_TYPE_BZREVERSAL & m_vertex[i+1].type))
				||
				(THRESHOLD_TYPE_BZREVERSAL == m_vertex[i].type || THRESHOLD_TYPE_BZREVERSAL == m_vertex[i+1].type)) {

				_crs_pt.type = THRESHOLD_TYPE_BZREVERSAL;
				_crs_pt.ext1 = 0.0;
			}
			else {
				_crs_pt.type = THRESHOLD_TYPE_INSTABILITY;

				// if ever there is a requirement for the relaxation radius to be
				// decided by where the instability threshold is crossed then the
				// commented-out code below may come in useful

				// calculate the relaxation radius for the intersection point
				//double edge_len = get_len(m_vertex[i], m_vertex[i+1]);
				//double ipt_to_crspt_len = get_len(m_vertex[i], _crs_pt);

				//_crs_pt.ext1 = m_vertex[i].ext1 + (ipt_to_crspt_len/edge_len)*(m_vertex[i+1].ext1 - m_vertex[i].ext1);
			}

			break;
		} // end of <if (seg_intersection(edge, _seg, i1, i2))> clause

	} // end of <for (i = 0; i < (m_vertex.size()-1) && !intersect; i++)> loop

	return i;
}
Exemple #2
0
 void arc_t::construct_segment( double outer, double inner, line_t& lbnd, line_t& rbnd, arc_t& seg, arc_t& seg2 ) const 
 {   
     check_calc();
     double &r = outer;
     const double &o = rad;
     const double &d = center.norm();
     
     if( r + o > d )
     {
         const double &s = (r + o + d)/2;
         const double &h = 2*(sqrt( s * (s-r) * (s-o) * (s-d) ) ) / d;
         const double &l = sqrt( r*r - h*h );
         
         const vector_t& p = (center.get_data() / d) * l;
         double angle = norm_angle_zero( atan2( center[1], center[0] ) - PRX_PI/2.0 );
         vector_t& c = hold_point;
         hold_point[0] = cos( angle );
         hold_point[1] = sin( angle );
         c *= h;
         
         points[0] = p + c;
         points[1] = p - c;
         if( on_ray( points[0].get_data() ) )
         {
             points[0].set_valid( true );
             points[0].set_interested_point( norm_angle_zero( atan2( points[0][1]-center[1], points[0][0]-center[0] ) ) );
         }
         else
         {
             points[0].set_valid( false );
         }
         if( on_ray( points[1].get_data() ) )
         {
             points[1].set_valid( true );
             points[1].set_interested_point( norm_angle_zero( atan2( points[1][1]-center[1], points[1][0]-center[0] ) ) );
         }
         else
         {
             points[1].set_valid( false );
         }
     }
     
     r = inner;
     
     if( r + o > d )
     {
         const double &s = (r + o + d)/2;
         const double &h = 2*(sqrt( s * (s-r) * (s-o) * (s-d) ) ) / d;
         const double &l = sqrt( r*r - h*h );
         
         const vector_t& p = (center.get_data() / d) * l;
         double angle = norm_angle_zero( atan2( center[1], center[0] ) - PRX_PI/2.0 );
         vector_t& c = hold_point;
         hold_point[0] = cos( angle );
         hold_point[1] = sin( angle );
         c *= h;
         
         points[2] = p + c;
         points[3] = p - c;
         if( on_ray( points[2].get_data() ) )
         {
             points[2].set_valid( true );
             points[2].set_interested_point( norm_angle_zero( atan2( points[2][1]-center[1], points[2][0]-center[0] ) ) );
         }
         else
         {
             points[2].set_valid( false );
         }
         if( on_ray( points[3].get_data() ) )
         {
             points[3].set_valid( true );
             points[3].set_interested_point( norm_angle_zero( atan2( points[3][1]-center[1], points[3][0]-center[0] ) ) );
         }
         else
         {
             points[3].set_valid( false );
         }
     }
     
     seg_intersection( &lbnd, hold_points, true );
     if( hold_points[0].is_valid() )
     {
         points[4] = hold_points[0];
     }
     if( hold_points[1].is_valid() )
     {
         points[5] = hold_points[1];
     }
     
     seg_intersection( &rbnd, hold_points, true );
     if( hold_points[0].is_valid() )
     {
         points[6] = hold_points[0];
     }
     if( hold_points[1].is_valid() )
     {
         points[7] = hold_points[1];
     }
     
     double start_angle = norm_angle_zero( atan2( point_b[1], point_b[0] ) );
     
     bool in = ( point_b.norm() < outer && point_b.norm() > inner ) && ( rbnd.side( point_b.get_data() ) > 0 && lbnd.side( point_b.get_data() ) < 0 );
     
     std::vector< intersection_point_t* > sort_points;
     for( unsigned i=0; i<8; ++i )
     {
         if( points[i].is_valid() )
         {
             points[i].set_index(0);
             sort_points.push_back( &points[i] );
         }
     }
     
     foreach( intersection_point_t* pt, sort_points )
     {
         double val = pt->get_sort_value();
         if( val < start_angle )
             pt->set_interested_point( val + (2*PRX_PI) );
     }