/*! */ 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() ) ); }
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; }
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; }
/*! */ 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 ) ); } } }
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; }
Segment2D Segment2D::operator-( const Vector2& Offset ) const { return Segment2D( m_Start - Offset, m_End - Offset ); }
/*! */ 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(); }
/*! */ 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() ); } }