Beispiel #1
0
    bool sphere_and_point_collision(const Point &segment_start, const Point &segment_end, double sphere_radius,
                                    const Point &point)
    {
        check_segment( segment_start, segment_end );

        return greater_or_equal( sphere_radius, distance_between_point_and_segment( point, segment_start, segment_end ) );
    }
Beispiel #2
0
    bool is_point_inside_triangle(const Point &point, const Triangle &triangle)
    {
        // TODO: check whether the point is in the same plane as triangle.
        // By now this function returns true if the _projection_ of the point is inside triangle
        const Vector u = triangle[1] - triangle[0];
        const Vector v = triangle[2] - triangle[0];
        const Vector r = point - triangle[0];
        
        // find components of r along u and v
        const double determinant = (u*u)*(v*v) - (u*v)*(u*v);
        check( determinant != 0, DegeneratedTriangleError() );

        const double ru = ( (r*u)*(v*v) - (u*v)*(r*v) ) / determinant;
        const double rv = ( (u*u)*(r*v) - (r*u)*(u*v) ) / determinant;

        return greater_or_equal( ru, 0 ) && greater_or_equal( rv, 0 ) && less_or_equal( ru + rv, 1 );
    }
Beispiel #3
0
 /**
 * \brief Greater than or equal to operator.
 */
 friend bool operator>= (Parent const& lhs, Parent const& rhs)
 {
     return greater_or_equal(lhs, rhs);
 }
Beispiel #4
0
    bool sphere_and_segment_collision(const Point &sphere_segment_start, const Point &sphere_segment_end, double sphere_radius,
                                      const Point &segment_start, const Point &segment_end,
                                      /*out*/ Point &collision_point)
    {
        check_segment( segment_start, segment_end );
        check_segment( sphere_segment_start, sphere_segment_end );

        const Vector L_sphere = (sphere_segment_end - sphere_segment_start).normalized();
        const Vector L_segment = (segment_end - segment_start).normalized();
        
        Point nearest_on_sphere_way, nearest_on_segment;
        nearest_points_on_lines( sphere_segment_start, L_sphere, segment_start, L_segment, nearest_on_sphere_way, nearest_on_segment);
        
        const double dist = distance( nearest_on_sphere_way, nearest_on_segment );
        
        if( L_sphere.is_collinear_to( L_segment ) )
        {
            // when the sphere is flying in parallel to the line, it's assumed to be no collision
            return false;
        }
        
        if( greater_or_equal( sphere_radius, dist ) )
        {
            // if distance between lines is less than radius
            const double perpendicular_length = sqrt( sphere_radius*sphere_radius - dist*dist );
            Point result = perpendicular_base( L_sphere, L_segment, nearest_on_segment, perpendicular_length );

            // now check that this collision point is inside the segment
            if( !is_point_between( result, segment_start, segment_end ) )
            {
                return false;
            }

            Vector normal; // normal, aimed from L_segment to L_sphere
            if( L_sphere.is_orthogonal_to(L_segment) )
            {
                normal = - L_sphere.normalized();
            }
            else
            {
                const Vector L_segment_other = (result - nearest_on_segment).normalized();
                assert( L_segment_other == L_segment || L_segment_other == -L_segment );
                // calculating normal, aimed from L_segment to L_sphere as double cross-product. L_segment_other is used instead of L_segment in order to avoid sign mess
                normal = cross_product( cross_product( L_sphere, L_segment_other ), L_segment_other ).normalized();
            }
            assert( !normal.is_zero() );
            Point sphere_center = result + perpendicular_length*normal + (nearest_on_sphere_way - nearest_on_segment); // sphere center is here at the moment of collision

            // now check that sphere center at the moment of collision is inside the segment
            if( !is_point_between( sphere_center, sphere_segment_start, sphere_segment_end ) )
            {
                return false;
            }

            // all checks passed => there is a collision
            collision_point = result;
            return true;
        }
        else
        {
            // otherwise, sphere flies too far, no collision
            return false;
        }
    }
Beispiel #5
0
 /**
 * \brief Greater than or equal to operator.
 */
 FRAMEWORK_ALWAYS_INLINE
 friend bool operator>= (Parent const& lhs, Parent const& rhs)
 {
     return greater_or_equal(lhs, rhs);
 }