/** * 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; }
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) ); }