void CDebugDrawer::DrawArrow(Vector2f aFrom, Vector2f aTo, Vector4f aColor) { if (myNumberOfRenderedLines+3 > myMaxLines) { return; } Vector2f direction = aTo - aFrom; direction = direction.Normalize(); direction *= 0.1f; Vector2f theNormal = direction.Normal(); theNormal *= 0.5f; myLineBuffer[myNumberOfRenderedLines]->myFromPosition = aFrom; myLineBuffer[myNumberOfRenderedLines]->myToPosition = aTo; myLineBuffer[myNumberOfRenderedLines]->myColor = aColor; myNumberOfRenderedLines++; myLineBuffer[myNumberOfRenderedLines]->myFromPosition = aTo; myLineBuffer[myNumberOfRenderedLines]->myToPosition = aTo - direction + theNormal; myLineBuffer[myNumberOfRenderedLines]->myColor = aColor; myNumberOfRenderedLines++; myLineBuffer[myNumberOfRenderedLines]->myFromPosition = aTo; myLineBuffer[myNumberOfRenderedLines]->myToPosition = aTo - direction - theNormal; myLineBuffer[myNumberOfRenderedLines]->myColor = aColor; myNumberOfRenderedLines++; }
float DistancetoLineSegment(const Vector2f& a, const Vector2f& b, const Vector2f& point) { Vector2f dist = b - a; float length = dist.Length(); float t = (point - a).Dot(dist); if(t < 0.0f) return (point - a).Length(); if(t > length) return (point - b).Length(); dist.Normalize(); if(dist == Vector2f::Zero) return (point - a).Length(); return (point - (a + dist * t)).Length(); }
void Camera::update( const float fDelta ) { static const float fMaxSpeed = 100.f; Vector2f vToTarget; if( m_eFollowMode == FOLLOW_ACTOR ) { if( m_pFollowTarget != nullptr ) { const Vector2f& vTargetPosition = m_pFollowTarget->GetPosition(); vToTarget = vTargetPosition - m_vCameraCenter; } } else if( m_eFollowMode == FOLLOW_POSITION ) { vToTarget = m_vSetFollowPosition - m_vCameraCenter; } if( ( fMaxSpeed * fMaxSpeed ) < vToTarget.Length2() ) { vToTarget = vToTarget.Normalize() * fMaxSpeed; } m_vCameraCenter += vToTarget * fDelta; }
//---------------------------------------------------------------------------- void PolygonDistance::ComputePerpendiculars (int numVertices, const Vector2f* vertices, const Vector2f& closest, Vector2f end[2]) { const float normLength = 40.0f; const float close = 0.1f; end[0] = closest; end[1] = closest; for (int i = 0; i < numVertices; ++i) { int j = (i + 1) % numVertices; float denom = vertices[i][0] - vertices[j][0]; if (denom == 0.0f) { // The edge is vertical. if (closest[1] == vertices[i][0]) { // The result lies on the edge. Vector2f diff0 = closest - vertices[0]; Vector2f diff1 = closest - vertices[1]; if (diff0.Length() > close && diff1.Length() > close) { // The result is on the edge but not a vertex. end[0] = closest + normLength*Vector2f::UNIT_X; end[1] = closest - normLength*Vector2f::UNIT_X; } return; } else { // The result is not on this edge, go to next edge. continue; } } // The edge is not vertical. float numer = closest[0] - vertices[j][0]; float t = numer/denom; if (t <= 0.0f || t >= 1.0f) { // The result is not in this line segment. continue; } float temp = Mathf::FAbs(t*vertices[i][1] + (1.0f - t)*vertices[j][1] - closest[1]); if (temp < close) { // The solution is on this edge. Vector2f diff2 = closest - vertices[0]; Vector2f diff3 = closest - vertices[1]; if (diff2.Length() > close && diff3.Length() > close) { // The result is on the edge but not a vertex. Vector2f norm = Vector2f(vertices[i][1] - vertices[j][1], -denom); norm.Normalize(); end[0] = closest + normLength*norm; end[1] = closest - normLength*norm; return; } } } }
int CVSwipeGesture::Process(CVPipeline * pipe) { // Check optical flow. int points = pipe->opticalFlowPoints.Size(); Vector2f direction; for (int i = 0; i < points; ++i) { OpticalFlowPoint & point = pipe->opticalFlowPoints[i]; direction += point.offset.NormalizedCopy(); } if (points) { framesWithFlow++; // std::cout<<"\nDirection: "<<direction; } // direction.y *= 0.5f; direction.Normalize(); float s0 = smoothing->GetFloat(); float s1 = 1 - s0; pointsSmoothed = pointsSmoothed * s0 + points * s1; // std::cout<<"\nOptical flow points "<<points; directionSmoothed = directionSmoothed * s0 + direction * s1; // Copy swipe-state to pipeline, before changes herein occur. pipe->swipeState = swipeState; // State-machine style now. switch(swipeState) { case SwipeState::IDLE: { if (pointsSmoothed > minPointsForSwipe->GetInt()) { std::cout<<"\nSwipe starting."; swipeStart = Time::Now(); swipeState = SwipeState::IN_SWIPE; swipeDirections.Clear(); framesWithFlow = 0; } break; } case SwipeState::IN_SWIPE: { if (maxFramesToAnalyze->GetInt() <= 0 || swipeDirections.Size() < maxFramesToAnalyze->GetInt()) { // std::cout<<"\nAdding smoothed direction: "<<directionSmoothed; swipeDirections.Add(directionSmoothed); } if (pointsSmoothed < minPointsBeforeLeavingSwipe->GetInt()) { std::cout<<"\nSwipe ending."; swipeState = SwipeState::SWIPE_ENDED; /// } break; } case SwipeState::SWIPE_ENDED: { Time now = Time::Now(); int duration = (now - swipeStart).Milliseconds(); std::cout<<"\nDuration: "<<duration; if (duration > maxSwipeDuration->GetInt() && maxSwipeDuration->GetInt() > 0) { std::cout<<"\nSwipe exceeded maximum duration. Ignored."; swipeState = SwipeState::IDLE; break; } if (framesWithFlow < minFramesWithFlow->GetInt()) { std::cout<<"\nFrames not enough, skipping this swipe! o.o"; } // Calculate average direction throughout the entire swipe-gesture. Vector2f averageDirection; for (int i = 0; i < swipeDirections.Size(); ++i) { averageDirection += swipeDirections[i]; } averageDirection /= swipeDirections.Size(); Vector2f averageDirectionNormalized = averageDirection.NormalizedCopy(); // TODO: Check for a local extreme instead of an average? pipe->swipeGestureDirection = averageDirectionNormalized; /// Check direction. std::cout<<"\nDetected swipe in direction: "<<pipe->swipeGestureDirection; swipeState = SwipeState::IDLE; break; } } return CVReturnType::SWIPES_GESTURES; }