* ctrl_slider.cpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: ctrl_slider.cpp,v 1.2 2004/01/11 17:12:17 asmax Exp $
+ * $Id: ctrl_slider.cpp,v 1.3 2004/02/01 21:13:04 ipkiss Exp $
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
m_curve.getPoint( m_rVariable.get(), xPos, yPos );
// Compute the resize factors
- float factorX = 0, factorY = 0;
+ float factorX, factorY;
getResizeFactors( factorX, factorY );
xPos = (int)(xPos * factorX);
yPos = (int)(yPos * factorY);
m_curve.getPoint( m_rVariable.get(), xPos, yPos );
// Compute the resize factors
- float factorX = 0, factorY = 0;
+ float factorX, factorY;
getResizeFactors( factorX, factorY );
xPos = (int)(xPos * factorX);
yPos = (int)(yPos * factorY);
EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;
// Compute the resize factors
- float factorX = 0, factorY = 0;
+ float factorX, factorY;
pThis->getResizeFactors( factorX, factorY );
+ // Get the position of the control
+ const Position *pPos = pThis->getPosition();
+
// Compute the offset
int tempX, tempY;
pThis->m_curve.getPoint( pThis->m_rVariable.get(), tempX, tempY );
- pThis->m_xOffset = pEvtMouse->getXPos() - (int)(tempX * factorX);
- pThis->m_yOffset = pEvtMouse->getYPos() - (int)(tempY * factorY);
+ pThis->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft()
+ - (int)(tempX * factorX);
+ pThis->m_yOffset = pEvtMouse->getYPos() - pPos->getTop()
+ - (int)(tempY * factorY);
pThis->captureMouse();
pThis->m_pImg = pThis->m_pImgDown;
const Position *pPos = pThis->getPosition();
// Compute the resize factors
- float factorX = 0, factorY = 0;
+ float factorX, factorY;
pThis->getResizeFactors( factorX, factorY );
- // XXX: This could be optimized a little bit
- if( pThis->m_curve.getMinDist(
- (int)((pEvtMouse->getXPos() - pPos->getLeft()) / factorX),
- (int)((pEvtMouse->getYPos() - pPos->getTop()) / factorY) ) < RANGE )
+ // Compute the relative position of the centre of the cursor
+ float relX = pEvtMouse->getXPos() - pPos->getLeft() - pThis->m_xOffset;
+ float relY = pEvtMouse->getYPos() - pPos->getTop() - pThis->m_yOffset;
+ // Ponderate with the resize factors
+ int relXPond = (int)(relX / factorX);
+ int relYPond = (int)(relY / factorY);
+
+ // Update the position
+ if( pThis->m_curve.getMinDist( relXPond, relYPond ) < RANGE )
{
- float percentage = pThis->m_curve.getNearestPercent(
- (int)((pEvtMouse->getXPos() - pThis->m_xOffset) / factorX),
- (int)((pEvtMouse->getYPos() - pThis->m_yOffset) / factorY) );
+ float percentage = pThis->m_curve.getNearestPercent( relXPond,
+ relYPond );
pThis->m_rVariable.set( percentage );
}
else
}
// Compute the resize factors
- float factorX = 0, factorY = 1.0;
+ float factorX, factorY;
getResizeFactors( factorX, factorY );
- return (m_curve.getMinDist( (int)(x / factorY),
+ return (m_curve.getMinDist( (int)(x / factorX),
(int)(y / factorY) ) < m_thickness );
}
if( rEvent.getAsString().find( "mouse:left:down" ) != string::npos )
{
// Compute the resize factors
- float factorX = 0, factorY = 1.0;
+ float factorX, factorY;
getResizeFactors( factorX, factorY );
// Get the position of the control
* bezier.cpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: bezier.cpp,v 1.2 2004/01/11 17:12:17 asmax Exp $
+ * $Id: bezier.cpp,v 1.3 2004/02/01 21:13:04 ipkiss Exp $
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
m_topVect.reserve( MAX_BEZIER_POINT + 1 );
// Calculate the first point
- getPoint( 0, oldx, oldy );
+ computePoint( 0, oldx, oldy );
m_leftVect[0] = oldx;
m_topVect[0] = oldy;
- // Compute the number of different points
+ // Calculate the other points
float percentage;
for( float j = 1; j <= MAX_BEZIER_POINT; j++ )
{
percentage = j / MAX_BEZIER_POINT;
- getPoint( percentage, cx, cy );
+ computePoint( percentage, cx, cy );
if( ( flag == kCoordsBoth && ( cx != oldx || cy != oldy ) ) ||
( flag == kCoordsX && cx != oldx ) ||
( flag == kCoordsY && cy != oldy ) )
{
+ m_percVect.push_back( percentage );
m_leftVect.push_back( cx );
m_topVect.push_back( cy );
oldx = cx;
oldy = cy;
}
}
- m_nbPoints = m_leftVect.size();
+ m_nbPoints = m_percVect.size();
+
+ // Small hack to ensure that the percentage of the last point is always 1
+ m_percVect[m_nbPoints - 1] = 1;
}
float Bezier::getNearestPercent( int x, int y ) const
{
int nearest = findNearestPoint( x, y );
- return (float)nearest / (float)(m_nbPoints - 1);
+ return m_percVect[nearest];
}
float Bezier::getMinDist( int x, int y ) const
{
- // XXX: duplicate code with findNearestPoint
- int minDist = (m_leftVect[0] - x) * (m_leftVect[0] - x) +
- (m_topVect[0] - y) * (m_topVect[0] - y);
-
- int dist;
- for( int i = 1; i < m_nbPoints; i++ )
- {
- dist = (m_leftVect[i] - x) * (m_leftVect[i] - x) +
- (m_topVect[i] - y) * (m_topVect[i] - y);
- if( dist < minDist )
- {
- minDist = dist;
- }
- }
- return sqrt( minDist );
+ int nearest = findNearestPoint( x, y );
+ return sqrt( (m_leftVect[nearest] - x) * (m_leftVect[nearest] - x) +
+ (m_topVect[nearest] - y) * (m_topVect[nearest] - y) );
}
void Bezier::getPoint( float t, int &x, int &y ) const
{
- // See http://astronomy.swin.edu.au/~pbourke/curves/bezier/ for a simple
- // explanation of the algorithm
- float xPos = 0;
- float yPos = 0;
- float coeff;
- for( int i = 0; i < m_nbCtrlPt; i++ )
+ // Find the precalculated point whose percentage is nearest from t
+ int refPoint = 0;
+ float minDiff = fabs( m_percVect[0] - t );
+
+ // The percentages are stored in increasing order, so we can stop the loop
+ // as soon as 'diff' starts increasing
+ float diff;
+ while( refPoint < m_nbPoints &&
+ (diff = fabs( m_percVect[refPoint] - t )) <= minDiff )
{
- coeff = computeCoeff( i, m_nbCtrlPt - 1, t );
- xPos += m_ptx[i] * coeff;
- yPos += m_pty[i] * coeff;
+ refPoint++;
+ minDiff = diff;
}
- // float cast to avoid strange truncatures
- // XXX: not very nice...
- x = (int)(float)xPos;
- y = (int)(float)yPos;
+ // The searched point is then (refPoint - 1)
+ // We know that refPoint > 0 because we looped at least once
+ x = m_leftVect[refPoint - 1];
+ y = m_topVect[refPoint - 1];
}
int Bezier::findNearestPoint( int x, int y ) const
{
- // XXX: duplicate code with getMinDist
// The distance to the first point is taken as the reference
int refPoint = 0;
int minDist = (m_leftVect[0] - x) * (m_leftVect[0] - x) +
}
+void Bezier::computePoint( float t, int &x, int &y ) const
+{
+ // See http://astronomy.swin.edu.au/~pbourke/curves/bezier/ for a simple
+ // explanation of the algorithm
+ float xPos = 0;
+ float yPos = 0;
+ float coeff;
+ for( int i = 0; i < m_nbCtrlPt; i++ )
+ {
+ coeff = computeCoeff( i, m_nbCtrlPt - 1, t );
+ xPos += m_ptx[i] * coeff;
+ yPos += m_pty[i] * coeff;
+ }
+
+ // Float cast to avoid strange truncatures
+ // XXX: not very nice...
+ x = (int)(float)xPos;
+ y = (int)(float)yPos;
+}
+
+
inline float Bezier::computeCoeff( int i, int n, float t ) const
{
return (power( t, i ) * power( 1 - t, (n - i) ) *
* bezier.hpp
*****************************************************************************
* Copyright (C) 2003 VideoLAN
- * $Id: bezier.hpp,v 1.3 2004/02/01 16:15:40 asmax Exp $
+ * $Id: bezier.hpp,v 1.4 2004/02/01 21:13:04 ipkiss Exp $
*
* Authors: Cyril Deguet <asmax@via.ecp.fr>
* Olivier Teulière <ipkiss@via.ecp.fr>
/// Return the percentage (between 0 and 1) of the curve point nearest
/// from (x, y)
-
float getNearestPercent( int x, int y ) const;
/// Return the distance of (x, y) to the curve
float getMinDist( int x, int y ) const;
- /// Get the coordinates of the point at t precent of
+ /// Get the coordinates of the point at t percent of
/// the curve (t must be between 0 and 1)
void getPoint( float t, int &x, int &y ) const;
/// Vectors with the coordinates of the different points of the curve
vector<int> m_leftVect;
vector<int> m_topVect;
+ /// Vector with the percentages associated with the points of the curve
+ vector<float> m_percVect;
/// Return the index of the curve point that is the nearest from (x, y)
int findNearestPoint( int x, int y ) const;
+ /// Compute the coordinates of a point corresponding to a given
+ /// percentage
+ void computePoint( float t, int &x, int &y ) const;
/// Helper function to compute a coefficient of the curve
inline float computeCoeff( int i, int n, float t ) const;
/// x^n