Example #1
0
/*!

*/
Vector2D
Segment2D::intersection( const Segment2D & other,
                         const bool allow_end_point ) const
{
    Vector2D sol = this->line().intersection( other.line() );

    if ( ! sol.isValid()
         || ! this->contains( sol )
         || ! other.contains( sol ) )
    {
        return Vector2D::INVALIDATED;
    }

    if ( ! allow_end_point
         && ! existIntersectionExceptEndpoint( other ) )
    {
        return Vector2D::INVALIDATED;
    }

    return sol;

#if 0
    // Following algorithm seems faster ther above.
    // In fact, the following algorithm slower...

    Vector2D ab = terminal() - origin();
    Vector2D dc = other.origin() - other.terminal();
    Vector2D ad = other.terminal() - origin();

    double det = dc.outerProduct( ab );

    if ( std::fabs( det ) < 1.0e-9 )
    {
        // area size is 0.
        // segments has same slope.
        std::cerr << "Segment2D::intersection()"
                  << " ***ERROR*** parallel segments"
                  << std::endl;
        return Vector2D::INVALIDATED;
    }

    double s = ( dc.x * ad.y - dc.y * ad.x ) / det;
    double t = ( ab.x * ad.y - ab.y * ad.x ) / det;

    if ( s < 0.0 || 1.0 < s || t < 0.0 || 1.0 < t )
    {
        return Vector2D::INVALIDATED;
    }

    return Vector2D( origin().x + ab.x * s, origin().y + ab.y * s );
#endif
}
Example #2
0
/*!

 */
void
ConvexHull::computeDirectMethod()
{
    clearResults();

    const size_t point_size = M_input_points.size();

    if ( point_size < 3 )
    {
        return;
    }

    for ( size_t i = 0; i < point_size - 1; ++i )
    {
        const Vector2D & p = M_input_points[i];

        for ( size_t j = i + 1; j < point_size; ++j )
        {
            const Vector2D & q = M_input_points[j];
            const Vector2D rel = q - p;

            bool valid = true;
            double last_value = 0.0;

            for ( size_t k = 0; k < point_size; ++k )
            {
                if ( k == i || k == j ) continue;

                const Vector2D & r = M_input_points[k];
                double outer_prod = rel.outerProduct( r - p );

                if ( std::fabs( outer_prod ) < 1.0e-6 )
                {
                    // point is on the line
                    if ( ( r - p ).r2() < rel.r2() )
                    {
                        // point is on the segment
                        valid = false;
                        break;
                    }
                }

                if ( ( outer_prod > 0.0 && last_value < 0.0 )
                     || ( outer_prod < 0.0 && last_value > 0.0 ) )
                {
                    // point exists in the opposite side
                    valid = false;
                    break;
                }

                last_value = outer_prod;
            }

            if ( valid )
            {
                M_vertices.push_back( p );
                M_vertices.push_back( q );

                if ( last_value < 0.0 )
                {
                    M_edges.push_back( Segment2D( p, q ) );
                }
                else
                {
                    M_edges.push_back( Segment2D( q, p ) );
                }
            }
        }
    }

    // sort vertices by counter clockwise order

    if ( ! M_vertices.empty() )
    {
        std::sort( M_vertices.begin() + 1,
                   M_vertices.end(),
                   AngleSortPredicate( M_vertices.front() ) );
        M_vertices.erase( std::unique( M_vertices.begin(), M_vertices.end(), Vector2D::Equal() ),
                          M_vertices.end() );
    }
}