static inline void apply(Info& info, Point1 const& /*p1*/, Point2 const& /*p2*/, IntersectionInfo const& iinfo) { info.rob_pi = iinfo.rpi(); info.rob_pj = iinfo.rpj(); info.rob_qi = iinfo.rqi(); info.rob_qj = iinfo.rqj(); }
static inline bool apply(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, bool is_p_first, bool is_p_last, bool is_q_first, bool is_q_last, TurnInfo const& tp_model, IntersectionInfo const& inters, method_type /*method*/, OutputIterator out) { std::size_t ip_count = inters.i_info().count; // no intersection points if ( ip_count == 0 ) return false; if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last ) return false; linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last); bool append0_last = analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, intersections.template get<0>(), tp_model, inters, 0, out); // NOTE: opposite && ip_count == 1 may be true! bool opposite = inters.d_info().opposite; // don't ignore only for collinear opposite bool result_ignore_ip0 = append0_last && ( ip_count == 1 || !opposite ); if ( intersections.template get<1>().p_operation == operation_none ) return result_ignore_ip0; bool append1_last = analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, intersections.template get<1>(), tp_model, inters, 1, out); // don't ignore only for collinear opposite bool result_ignore_ip1 = append1_last && !opposite /*&& ip_count == 2*/; return result_ignore_ip0 || result_ignore_ip1; }
const std::pair<geo::IntersectionInfo, const GeneralPlane*> get_intersection( const geo::HalfLine& line ) const { using namespace geo; const GeneralPlane* pplane; IntersectionInfo info(no_intersection); PlaneContainer::const_iterator it=planes_.begin(); double distance=999999; for(; it != planes_.end(); it++) { IntersectionInfo temp = it->intersect( line ); if(temp.valid()) { if(temp.distance() < distance) { // ここに表裏判定の部分も入れる必要がある。 info=temp; distance = temp.distance(); pplane = &(*it); } } } return std::pair<IntersectionInfo, const GeneralPlane*>(info, pplane); }
static inline bool handle_internal(Point1 const& /*i1*/, Point1 const& /*j1*/, Point1 const& /*k1*/, Point2 const& i2, Point2 const& j2, Point2 const& /*k2*/, RobustPoint1 const& ri1, RobustPoint1 const& rj1, RobustPoint1 const& /*rk1*/, RobustPoint2 const& ri2, RobustPoint2 const& rj2, RobustPoint2 const& rk2, bool first1, bool last1, bool first2, bool last2, bool ip_i2, bool ip_j2, TurnInfo const& tp_model, IntersectionInfo const& inters, unsigned int ip_index, operation_type & op1, operation_type & op2) { boost::ignore_unused_variable_warning(i2); boost::ignore_unused_variable_warning(j2); boost::ignore_unused_variable_warning(ip_index); boost::ignore_unused_variable_warning(tp_model); if ( !first2 && !last2 ) { if ( first1 ) { #ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR // may this give false positives for INTs? typename IntersectionResult::point_type const& inters_pt = inters.i_info().intersections[ip_index]; BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt)); BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt)); #endif if ( ip_i2 ) { // don't output this IP - for the first point of other geometry segment op1 = operation_none; op2 = operation_none; return true; } else if ( ip_j2 ) { side_calculator<RobustPoint1, RobustPoint2, RobustPoint2> side_calc(ri2, ri1, rj1, ri2, rj2, rk2); std::pair<operation_type, operation_type> operations = operations_of_equal(side_calc); // TODO: must the above be calculated? // wouldn't it be enough to check if segments are collinear? if ( operations_both(operations, operation_continue) ) { if ( op1 != operation_union || op2 != operation_union || ! ( G1Index == 0 ? inters.is_spike_q() : inters.is_spike_p() ) ) { // THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE! bool opposite = inters.d_info().opposite; op1 = operation_intersection; op2 = opposite ? operation_union : operation_intersection; } } else { BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union)); //op1 = operation_union; //op2 = operation_union; } return true; } // else do nothing - shouldn't be handled this way } else if ( last1 ) { #ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR // may this give false positives for INTs? typename IntersectionResult::point_type const& inters_pt = inters.i_info().intersections[ip_index]; BOOST_GEOMETRY_ASSERT(ip_i2 == equals::equals_point_point(i2, inters_pt)); BOOST_GEOMETRY_ASSERT(ip_j2 == equals::equals_point_point(j2, inters_pt)); #endif if ( ip_i2 ) { // don't output this IP - for the first point of other geometry segment op1 = operation_none; op2 = operation_none; return true; } else if ( ip_j2 ) { side_calculator<RobustPoint1, RobustPoint2, RobustPoint2> side_calc(ri2, rj1, ri1, ri2, rj2, rk2); std::pair<operation_type, operation_type> operations = operations_of_equal(side_calc); // TODO: must the above be calculated? // wouldn't it be enough to check if segments are collinear? if ( operations_both(operations, operation_continue) ) { if ( op1 != operation_blocked || op2 != operation_union || ! ( G1Index == 0 ? inters.is_spike_q() : inters.is_spike_p() ) ) { // THIS IS WRT THE ORIGINAL SEGMENTS! NOT THE ONES ABOVE! bool second_going_out = inters.i_info().count > 1; op1 = operation_blocked; op2 = second_going_out ? operation_union : operation_intersection; } } else { BOOST_GEOMETRY_ASSERT(operations_combination(operations, operation_intersection, operation_union)); //op1 = operation_blocked; //op2 = operation_union; } return true; } // else do nothing - shouldn't be handled this way } // else do nothing - shouldn't be handled this way } return false; }
static inline bool analyse_segment_and_assign_ip(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, bool is_p_first, bool is_p_last, bool is_q_first, bool is_q_last, linear_intersections::ip_info const& ip_info, TurnInfo const& tp_model, IntersectionInfo const& inters, unsigned int ip_index, OutputIterator out) { #ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS_LINEAR_LINEAR // may this give false positives for INTs? typename IntersectionResult::point_type const& inters_pt = result.template get<0>().intersections[ip_index]; BOOST_GEOMETRY_ASSERT(ip_info.is_pi == equals::equals_point_point(pi, inters_pt)); BOOST_GEOMETRY_ASSERT(ip_info.is_qi == equals::equals_point_point(qi, inters_pt)); BOOST_GEOMETRY_ASSERT(ip_info.is_pj == equals::equals_point_point(pj, inters_pt)); BOOST_GEOMETRY_ASSERT(ip_info.is_qj == equals::equals_point_point(qj, inters_pt)); #endif // TODO - calculate first/last only if needed bool is_p_first_ip = is_p_first && ip_info.is_pi; bool is_p_last_ip = is_p_last && ip_info.is_pj; bool is_q_first_ip = is_q_first && ip_info.is_qi; bool is_q_last_ip = is_q_last && ip_info.is_qj; bool append_first = EnableFirst && (is_p_first_ip || is_q_first_ip); bool append_last = EnableLast && (is_p_last_ip || is_q_last_ip); operation_type p_operation = ip_info.p_operation; operation_type q_operation = ip_info.q_operation; if ( append_first || append_last ) { bool handled = handle_internal<0>(pi, pj, pk, qi, qj, qk, inters.rpi(), inters.rpj(), inters.rpk(), inters.rqi(), inters.rqj(), inters.rqk(), is_p_first_ip, is_p_last_ip, is_q_first_ip, is_q_last_ip, ip_info.is_qi, ip_info.is_qj, tp_model, inters, ip_index, p_operation, q_operation); if ( !handled ) { handle_internal<1>(qi, qj, qk, pi, pj, pk, inters.rqi(), inters.rqj(), inters.rqk(), inters.rpi(), inters.rpj(), inters.rpk(), is_q_first_ip, is_q_last_ip, is_p_first_ip, is_p_last_ip, ip_info.is_pi, ip_info.is_pj, tp_model, inters, ip_index, q_operation, p_operation); } if ( p_operation != operation_none ) { method_type method = endpoint_ip_method(ip_info.is_pi, ip_info.is_pj, ip_info.is_qi, ip_info.is_qj); turn_position p_pos = ip_position(is_p_first_ip, is_p_last_ip); turn_position q_pos = ip_position(is_q_first_ip, is_q_last_ip); // handle spikes // P is spike and should be handled if ( !is_p_last && ip_info.is_pj // this check is redundant (also in is_spike_p) but faster && inters.i_info().count == 2 && inters.is_spike_p() ) { assign(pi, qi, inters.result(), ip_index, method, operation_blocked, q_operation, p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out); assign(pi, qi, inters.result(), ip_index, method, operation_intersection, q_operation, p_pos, q_pos, is_p_first_ip, is_q_first_ip, true, false, tp_model, out); } // Q is spike and should be handled else if ( !is_q_last && ip_info.is_qj // this check is redundant (also in is_spike_q) but faster && inters.i_info().count == 2 && inters.is_spike_q() ) { assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_blocked, p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out); assign(pi, qi, inters.result(), ip_index, method, p_operation, operation_intersection, p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, true, tp_model, out); } // no spikes else { assign(pi, qi, inters.result(), ip_index, method, p_operation, q_operation, p_pos, q_pos, is_p_first_ip, is_q_first_ip, false, false, tp_model, out); } } } return append_last; }