예제 #1
0
/*!

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

    const size_t point_size = M_input_points.size();

    if ( point_size < 3 )
    {
        return;
    }

    size_t min_index = getMinPointIndex();

    if ( min_index == size_t( -1 ) )
    {
        return;
    }

    sortPointsByAngleFrom( min_index );

    M_vertices = M_input_points;

    size_t top = 1;
    for ( size_t i = 2; i < point_size; ++i )
    {
        while ( is_clockwise( M_vertices[top-1],
                              M_vertices[top],
                              M_input_points[i] ) )
        {
            --top;
        }

        ++top;

        std::swap( M_vertices[top], M_vertices[i] );
    }

    ++top;

    M_vertices.erase( M_vertices.begin() + top,
                      M_vertices.end() );

    VertexCont::iterator p = M_vertices.begin();
    VertexCont::iterator n = p;
    ++n;
    for ( ; n != M_vertices.end(); ++n )
    {
        M_edges.push_back( Segment2D( *p, *n ) );
        p = n;
    }
    M_edges.push_back( Segment2D( M_vertices.back(), M_vertices.front() ) );
}
예제 #2
0
bool Segment2D::Intersects( const Triangle2D& Tri, CollisionInfo2D* const pInfo /*= NULL*/ ) const
{
	CollisionInfo2D Info;
	CollisionInfo2D MinInfo;

	if( pInfo )
	{
		Info.CopyInParametersFrom( *pInfo );
	}

	const Segment2D SegmentA = Segment2D( Tri.m_Vec1, Tri.m_Vec2 );
	const Segment2D SegmentB = Segment2D( Tri.m_Vec1, Tri.m_Vec3 );
	const Segment2D SegmentC = Segment2D( Tri.m_Vec2, Tri.m_Vec3 );

	if( Intersects( SegmentA, &Info ) )
	{
		if( Info.m_HitT < MinInfo.m_HitT || !MinInfo.m_Collision )
		{
			MinInfo = Info;
		}
	}

	if( Intersects( SegmentB, &Info ) )
	{
		if( Info.m_HitT < MinInfo.m_HitT || !MinInfo.m_Collision )
		{
			MinInfo = Info;
		}
	}

	if( Intersects( SegmentC, &Info ) )
	{
		if( Info.m_HitT < MinInfo.m_HitT || !MinInfo.m_Collision )
		{
			MinInfo = Info;
		}
	}

	if( MinInfo.m_Collision )
	{
		if( pInfo )
		{
			pInfo->CopyOutParametersFrom( MinInfo );
		}
		return true;
	}

	return false;
}
예제 #3
0
bool Hole:: CheckInPoly(Point3D p3D1,Point3D p3D2,Point3D p3D3,Point3D p3D4,Point3D check3D, View perspective)
{
	 Point2D p1 = Point2D(p3D1,perspective);
	 Point2D p2 = Point2D(p3D2,perspective);
	 Point2D p3 = Point2D(p3D3,perspective);
	 Point2D p4 = Point2D(p3D4,perspective);

	 Point2D check = Point2D(check3D,perspective);

	 Segment2D *polySegments = new Segment2D[4];
	 polySegments[0] = Segment2D(p1,p2);
	 polySegments[1] = Segment2D(p2,p3);
	 polySegments[2] = Segment2D(p3,p4);
	 polySegments[3] = Segment2D(p4,p1);

	 Segment2D *lines = new Segment2D[4];
	 lines[0] = Segment2D(check,p1);
	 lines[1] = Segment2D(check,p2);
	 lines[2] = Segment2D(check,p3);
	 lines[3] = Segment2D(check,p4);

	 if(lines[0].Intersects(polySegments[1]))
	 {
	  return false;
	 }
	 if(lines[0].Intersects(polySegments[2]))
	 {
	  return false;
	 }
	 if(lines[1].Intersects(polySegments[2]))
	 {
	  return false;
	 }
	 if(lines[1].Intersects(polySegments[3]))
	 {
	  return false;
	 }
	 if(lines[2].Intersects(polySegments[3]))
	 {
	  return false;
	 }
	 if(lines[2].Intersects(polySegments[0]))
	 {
	  return false;
	 }
	 if(lines[3].Intersects(polySegments[0]))
	 {
	  return false;
	 }
	 if(lines[3].Intersects(polySegments[1]))
	 {
	  return false;
	 }
	 return true;
}
예제 #4
0
/*!

*/
void
CoachDebugClient::addLine( const Vector2D & from,
                           const Vector2D & to )
{
    if ( M_on )
    {
        if ( M_lines.size() < MAX_LINE )
        {
            M_lines.push_back( Segment2D( from, to ) );
        }
    }
}
예제 #5
0
Vector2 View::ProjectAndClipToScreen( const Vector& Location ) const
{
	const Vector4			ProjectedLocation4D	= Project( Location );
	Vector2					ProjectedLocation2D;

	if( Abs( ProjectedLocation4D.w ) < EPSILON )
	{
		ProjectedLocation2D = ProjectedLocation4D;
	}
	else
	{
		ProjectedLocation2D = ProjectedLocation4D / ProjectedLocation4D.w;

		if( ProjectedLocation4D.w < 0.0f )
		{
			// Project beyond [-1,1] if location is behind view.
			ProjectedLocation2D = ProjectedLocation2D.GetNormalized() * -2.0f;
		}
	}

	static const Vector2	kScreenScale		= Vector2( 0.5f, -0.5f );
	static const Vector2	kScreenOffset		= Vector2( 0.5f, 0.5f );
	static const Vector2	kScreenMin			= Vector2( 0.0f, 0.0f );
	static const Vector2	kScreenMid			= Vector2( 0.5f, 0.5f );
	static const Vector2	kScreenMax			= Vector2( 1.0f, 1.0f );
	static const Box2D		kScreenBox			= Box2D( kScreenMin, kScreenMax );
	Vector2					ScreenLocation		= ( ProjectedLocation2D * kScreenScale ) + kScreenOffset;
	const Segment2D			ScreenSegment		= Segment2D( ScreenLocation, kScreenMid );

	CollisionInfo2D			Info;
	if( ScreenSegment.Intersects( kScreenBox, &Info ) )
	{
		ScreenLocation = Info.m_Intersection;
	}

	ScreenLocation.x = Clamp( ScreenLocation.x, 0.0f, 1.0f );
	ScreenLocation.y = Clamp( ScreenLocation.y, 0.0f, 1.0f );

	return ScreenLocation;
}
예제 #6
0
Segment2D Segment2D::operator-( const Vector2& Offset ) const
{
	return Segment2D( m_Start - Offset, m_End - Offset );
}
예제 #7
0
/*!

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

    const size_t point_size = M_input_points.size();

    if ( point_size < 3 )
    {
        return;
    }

    size_t min_index = getMinPointIndex();

    if ( min_index == size_t( -1 ) )
    {
        return;
    }

#ifdef DEBUG_PRINT
    std::cerr << "min_point=" min_index << ":" << M_input_points[min_index] << std::endl;
#endif

    std::set< size_t > vertices; // temporal set for checking already used vertices.

    M_vertices.push_back( M_input_points[min_index] );

    size_t current_index = min_index;
    Vector2D current_point = M_input_points[min_index];

    for ( size_t loop_count = 0; loop_count <= point_size; ++loop_count ) // while ( 1 )
    {
        //std::cerr << "loop " << loop_count
        //          << " base=" << current_index << ':' << current_point << std::endl;

        size_t candidate = 0;
        for ( size_t i = 0; i < point_size; ++i )
        {
            if ( i == current_index ) continue;
            if ( vertices.find( i ) != vertices.end() ) continue;

            candidate = i;
            break;
        }

        for ( size_t i = candidate + 1; i < point_size; ++i )
        {
            if ( i == current_index ) continue;
            if ( vertices.find( i ) != vertices.end() ) continue;

            const Vector2D & p = M_input_points[candidate];
            const Vector2D & q = M_input_points[i];

            double area = Triangle2D::double_signed_area( current_point, p, q );

            if ( area < 0.0 )
            {
                candidate = i;
            }
            else if ( area < 1.0e-6 )
            {
                if ( current_point.dist2( p ) > current_point.dist2( q ) )
                {
                    candidate = i;
                }
            }
        }

        current_index = candidate;
        current_point = M_input_points[current_index];
        vertices.insert( current_index );
        M_vertices.push_back( current_point );

        if ( current_index == min_index )
        {
            break;
        }

        //std::cerr << "updated to " << current_index << ":" << M_input_points[current_index] << std::endl;
    }

    VertexCont::iterator p = M_vertices.begin();
    VertexCont::iterator n = p;
    ++n;
    for ( ; n != M_vertices.end(); ++n )
    {
        M_edges.push_back( Segment2D( *p, *n ) );
        p = n;
    }
    M_vertices.pop_back();
}
예제 #8
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() );
    }
}