int main() { // expected (-5,2)/(5,-2)/(-5,2)/(5,2)/(5,2) (7.5,3) (2.5,1) cerr << RotateCCW90(PT(2,5)) << endl; cerr << RotateCW90(PT(2,5)) << endl; cerr << RotateCCW(PT(2,5),M_PI/2) << endl; cerr << ProjectPointLine(PT(-5,-2), PT(10,4), PT(3,7)) << endl; cerr << ProjectPointSegment(PT(-5,-2), PT(10,4), PT(3,7)) << " " << ProjectPointSegment(PT(7.5,3), PT(10,4), PT(3,7)) << " " << ProjectPointSegment(PT(-5,-2), PT(2.5,1), PT(3,7)) << endl; // expected 6.78903/1 0 1/0 0 1/1 1 1 0/(1,2)/(1,1) cerr << DistancePointPlane(4,-4,3,2,-2,5,-8) << endl; cerr << LinesParallel(PT(1,1), PT(3,5), PT(2,1), PT(4,5)) << " " << LinesParallel(PT(1,1), PT(3,5), PT(2,0), PT(4,5)) << " " << LinesParallel(PT(1,1), PT(3,5), PT(5,9), PT(7,13)) << endl; cerr << LinesCollinear(PT(1,1), PT(3,5), PT(2,1), PT(4,5)) << " " << LinesCollinear(PT(1,1), PT(3,5), PT(2,0), PT(4,5)) << " " << LinesCollinear(PT(1,1), PT(3,5), PT(5,9), PT(7,13)) << endl; cerr << SegmentsIntersect(PT(0,0), PT(2,4), PT(3,1), PT(-1,3)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(4,3), PT(0,5)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(2,-1), PT(-2,1)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(5,5), PT(1,7)) << endl; cerr << ComputeLineIntersection(PT(0,0),PT(2,4),PT(3,1),PT(-1,3)) << endl; cerr << ComputeCircleCenter(PT(-3,4), PT(6,1), PT(4,5)) << endl; vector<PT> v; v.push_back(PT(0,0)); v.push_back(PT(5,0)); v.push_back(PT(5,5)); v.push_back(PT(0,5)); // expected: 1 1 1 0 0 cerr << PointInPolygon(v, PT(2,2)) << " " << PointInPolygon(v, PT(2,0)) << " " << PointInPolygon(v, PT(0,2)) << " " << PointInPolygon(v, PT(5,2)) << " " << PointInPolygon(v, PT(2,5)) << endl; // expected: 0 1 1 1 1 cerr << PointOnPolygon(v, PT(2,2)) << " " << PointOnPolygon(v, PT(2,0)) << " " << PointOnPolygon(v, PT(0,2)) << " " << PointOnPolygon(v, PT(5,2)) << " " << PointOnPolygon(v, PT(2,5)) << endl; // expected: (1,6)/(5,4) (4,5)//(4,5) (5,4)//(4,5) (5,4) vector<PT> u = CircleLineIntersection(PT(0,6), PT(2,6), PT(1,1), 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleLineIntersection(PT(0,9), PT(9,0), PT(1,1), 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(10,10), 5, 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(8,8), 5, 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(4.5,4.5), 10, sqrt(2.0)/2.0); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(4.5,4.5), 5, sqrt(2.0)/2.0); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; // area should be 5.0; centroid should be (1.1666666, 1.166666) PT pa[] = {PT(0,0), PT(5,0), PT(1,1), PT(0,5)}; vector<PT> p(pa, pa+4); PT c = ComputeCentroid(p); cerr << "Area: " << ComputeArea(p) << endl; cerr << "Centroid: " << c << endl; }
// -------------------------------------------------------------------------------------------- // Ermittlung der Cursorposition bei 2 Kreisen HRESULT CRestrictLine::CursorToCircleCircle (LPARAM lParam, Point MSPt, Point MPt1, int iRad1, Point MPt2, int iRad2, POINT* pPTCur) { bool bTwice; // 2 Schnittpunkte (true) bzw. 1 Berührungspunkt (false) Point SectPt1, SectPt2; SectScreen ssRet = CircleCircleIntersection (MPt1, iRad1, MPt2, iRad2, bTwice, SectPt1, SectPt2); if (INSECT == ssRet) { if (bTwice) CursorToNearbyPoint (MSPt, SectPt1, SectPt2, pPTCur); else *pPTCur = (POINT&)SectPt1; return S_OK; } ResString rsCapt (ResID (IDS_LONGCLASSNAME, pRF), 50); if (OUTSECT == ssRet) { ResString rsText (ResID (IDS_OUTSECTPOINT, pRF), 200); if (IDYES == MessageBox (__hWndM, rsText.Addr(), rsCapt.Addr(), MB_ICONQUESTION | MB_YESNO)) { if (bTwice) ExpandingSreenSection (SectPt1, SectPt2); else ExpandingSreenSection (SectPt1); pPTCur->x = 0; // an dieser Stelle könnte mehr Aufwand getrieben werden, damit die NEUE Position pPTCur->y = 0; // von SectPt nach der Vergrößerung des Sichtausschnittes ermittelt wird !!!!!!! return S_OK; } return S_FALSE; // IDNO } if (INOUTSECT == ssRet) { ResString rsText (ResID (IDS_OUTSECTPOINT, pRF), 200); if (IDYES == MessageBox (__hWndM, rsText.Addr(), rsCapt.Addr(), MB_ICONQUESTION | MB_YESNO)) { ExpandingSreenSection (SectPt1, SectPt2); CursorToNearbyPoint (MSPt, SectPt1, SectPt2, pPTCur); return S_OK; } CursorToNearbyPoint (MSPt, SectPt1, SectPt2, pPTCur); return S_FALSE; // IDNO } if (INFISECT == ssRet) // beide Kreise sind deckungsgleich return CursorTo1RestrictLine (lParam, pPTCur); if (NOSECT == ssRet) { ResString rsText (ResID (IDS_NOSECTPOINT, pRF), 250); MessageBox (__hWndM, rsText.Addr(), rsCapt.Addr(), MB_ICONEXCLAMATION | MB_OK); pPTCur->x = -1; pPTCur->y = -1; return S_FALSE; } DEX_Error (RC_RestrictLine, EC_NOINTERSECTION); return E_FAIL; } // CursorToCircleCircle
int Game::Update( double p_DeltaTime ) { // ///////////////////////////////////////////// // INPUT // Exit if we press Escape if( KeyIsJustPressed( SDLK_ESCAPE ) ) { return 1; } if( KeyIsDown( SDLK_w ) ) { m_Player.BurstForwards( ); } else if( KeyIsDown( SDLK_s ) ) { m_Player.BurstBackwards( ); } if( KeyIsDown( SDLK_a ) ) { m_Player.BurstLeft( ); } else if( KeyIsDown( SDLK_d ) ) { m_Player.BurstRight( ); } // Shoot pumps / lazer m_ActiveLazer = false; if( KeyIsDown( SDLK_SPACE ) ) { if( m_PumpBullets.size( ) == 0 ) { // Shoot bullets if( !m_Planets[ m_CurrPlanet ].IsPumpActive( ) && KeyIsJustPressed( SDLK_SPACE ) ) { PumpBullet * pPumpBullet = new PumpBullet( ); pPumpBullet->SetPosition( m_Player.GetPosition( ) ); pPumpBullet->SetDirection( m_Player.GetViewDirection( ) ); pPumpBullet->SetSpeed( m_StartBulletSpeed ); pPumpBullet->SetColor( m_Player.GetColor( ) ); m_PumpBullets.push_back( pPumpBullet ); } // Shoot lazer else if( m_Planets[ m_CurrPlanet ].IsPumpActive( ) ) { m_ActiveLazer = true; } } } // Fill test if( KeyIsDown( SDLK_z ) ) { if( m_Planets[ m_CurrPlanet ].GetResources( ) != 1.0f ) { m_Planets[ m_CurrPlanet ].SetResources( m_Planets[ m_CurrPlanet ].GetResources( ) + ( 0.25f * p_DeltaTime) ); } } else if( KeyIsDown( SDLK_x ) ) { if( m_Planets[ m_CurrPlanet ].GetResources( ) != 0.0f ) { m_Planets[ m_CurrPlanet ].SetResources( m_Planets[ m_CurrPlanet ].GetResources( ) - ( 0.25f * p_DeltaTime) ); } } // ////////////////////////////////////////////////////////////// // Game update // Update the player m_Player.Update( p_DeltaTime ); // Update the planet m_Planets[ m_CurrPlanet ].Update( p_DeltaTime ); // Update all pump bullets UpdatePumpBullets( p_DeltaTime ); const LDE::Vector2f pumpPosition = m_Planets[ m_CurrPlanet ].GetGlobalPumpPosition( ); // Update the lazer m_LazerHittingPump = false; if( m_ActiveLazer ) { m_LazerPoints[ 0 ] = m_Player.GetPosition( ); m_LazerPoints[ 1 ] = m_Player.GetPosition( ) + ( m_Player.GetViewDirection( ) * 1000.0f ); // Check if any bullet hit the planet // Get the In and Out point of the intersection LDE::Vector2f inPump; LDE::Vector2f out; int pumpCol = LDE::LineCircleIntersection( m_LazerPoints[ 0 ], m_LazerPoints[ 1 ], pumpPosition, m_Planets[ m_CurrPlanet ].GetPumpSize( ), inPump, out); LDE::Vector2f inPlanet; int planetCol = LDE::LineCircleIntersection( m_LazerPoints[ 0 ], m_LazerPoints[ 1 ], m_Planets[ m_CurrPlanet ].GetPosition( ), m_Planets[ m_CurrPlanet ].GetSize( ), inPlanet, out); if( pumpCol == 1 && planetCol == 1) { float planetDist = LDE::Vector2f( m_LazerPoints[ 0 ] - inPlanet ).Magnitude( ); float pumpDist = LDE::Vector2f( m_LazerPoints[ 0 ] - inPump ).Magnitude( ); if( pumpDist <= planetDist ) { m_LazerPoints[ 1 ] = inPump; m_Planets[ m_CurrPlanet ].DrainPlanet( ); } else { m_LazerPoints[ 1 ] = inPlanet; } } else if( pumpCol == 1) { m_LazerPoints[ 1 ] = inPump; m_Planets[ m_CurrPlanet ].DrainPlanet( ); } else if( planetCol == 1) { m_LazerPoints[ 1 ] = inPlanet; } } // Add planet gravity if we are close enought LDE::Vector2f planetDirection = m_Planets[ m_CurrPlanet ].GetPosition( ) - m_Player.GetPosition( ); float planetDistance = planetDirection.Magnitude( ); const float planetGravityStart = m_Planets[ m_CurrPlanet ].GetSize( ) * 7.5f; if( planetDistance <= planetGravityStart ) { float gravityPower = 1.0f - ( planetDistance / planetGravityStart ); gravityPower *= 35.0f; LDE::Vector2f gravityVector = planetDirection.Normal( ) * gravityPower * p_DeltaTime * (m_Planets[ m_CurrPlanet ].GetSize( ) / 50.0f ); m_Player.SetDirection( m_Player.GetDirection( ) + gravityVector ); } // Collision detect the player and the player/pump if( CircleCircleIntersection( m_Player.GetPosition( ), m_StartPlayerRadius, m_Planets[ m_CurrPlanet ].GetPosition( ), m_Planets[ m_CurrPlanet ].GetSize( ) ) ) { // We died! ResetGame( ); } // Are we coliding with the pump? if( CircleCircleIntersection( m_Player.GetPosition( ), m_StartPlayerRadius, pumpPosition, m_Planets[ m_CurrPlanet ].GetPumpSize( ) ) ) { // We died! ResetGame( ); return 0; } //std::cout << pumpPosition.x << " " << pumpPosition.y << std::endl; // Are we outside the navigation system? Then reset if( planetDistance >= m_StartMaxPlanetRange + m_Planets[ m_CurrPlanet ].GetSize( ) ) { // We are lost! ResetGame( ); return 0; } // Are we out of time? m_GameTimer.Stop( ); if( m_GameTimer.GetTime( ) >= m_BestTime ) { ResetGame( ); return 0; } // Update the overlay alpha which is depending on the planet distance const float distMaxSurface = m_StartMaxPlanetRange + m_Planets[ m_CurrPlanet ].GetSize( ); const float distToSurface = planetDistance - m_Planets[ m_CurrPlanet ].GetSize( ); const float minOffset = distToSurface / 2.0f; const float maxOffset = distToSurface; const float offsetDiff1 = minOffset / distToSurface; const float offsetDiff2 = 1.0f / offsetDiff1; m_OverlayAlpha = ((distToSurface / distMaxSurface ) * offsetDiff2 ) - offsetDiff1; m_OverlayAlpha = std::max( 0.0f, m_OverlayAlpha ); // Is the current planet out of resources? if( m_Planets[ m_CurrPlanet ].GetResources( ) == 0 ) { if( m_CurrPlanet < PLANET_COUNT - 1 ) { m_CurrPlanet++; // Set the planet's start position to the pump's position m_Planets[ m_CurrPlanet ].SetPosition( pumpPosition ); } // We won the game. else { WinGame( ); } } return 0; }