]> git.sesse.net Git - vlc/commitdiff
* modules/gui/skins2/bezier.*: Compute the points coordinates only once
authorOlivier Teulière <ipkiss@videolan.org>
Sun, 1 Feb 2004 21:13:04 +0000 (21:13 +0000)
committerOlivier Teulière <ipkiss@videolan.org>
Sun, 1 Feb 2004 21:13:04 +0000 (21:13 +0000)
 * modules/gui/skins2/ctrl_slider.cpp: Fixed a couple of bugs

modules/gui/skins2/controls/ctrl_slider.cpp
modules/gui/skins2/utils/bezier.cpp
modules/gui/skins2/utils/bezier.hpp

index b3cce07b1de20576fe908a1d4838eb85e55314db..2b20657ec51f9fcf7d84c75dc1d34e2d0ad005d1 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -133,7 +133,7 @@ bool CtrlSliderCursor::mouseOver( int x, int y ) const
         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);
@@ -157,7 +157,7 @@ void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest )
         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);
@@ -190,14 +190,19 @@ void CtrlSliderCursor::transOverDown( SkinObject *pCtrl )
     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;
@@ -245,17 +250,21 @@ void CtrlSliderCursor::transMove( SkinObject *pCtrl )
     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
@@ -326,10 +335,10 @@ bool CtrlSliderBg::mouseOver( int x, int y ) const
     }
 
     // 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 );
 }
 
@@ -339,7 +348,7 @@ void CtrlSliderBg::handleEvent( EvtGeneric &rEvent )
     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
index 5c4118ccc22d4d107328782fb5fe80f4e57dcf68..fd4f6210e7012ec48ef425fd3466d3f1594c369d 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -50,75 +50,69 @@ Bezier::Bezier( intf_thread_t *p_intf, const vector<float> &rAbscissas,
     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];
 }
 
 
@@ -152,7 +146,6 @@ int Bezier::getHeight() const
 
 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) +
@@ -174,6 +167,27 @@ int Bezier::findNearestPoint( int x, int y ) const
 }
 
 
+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) ) *
index 93d24a447468d12f44878033a886fb8f5fabd4de..7746f3446f1caa8c17af86d2dda7159a892602fc 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -53,13 +53,12 @@ class Bezier: public SkinObject
 
         /// 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;
 
@@ -83,9 +82,14 @@ class Bezier: public SkinObject
         /// 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