Commit 675864e2 authored by Olivier Teulière's avatar Olivier Teulière

* modules/gui/skins2/bezier.*: Compute the points coordinates only once

 * modules/gui/skins2/ctrl_slider.cpp: Fixed a couple of bugs
parent d1cf41c4
......@@ -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 Teulire <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
......
......@@ -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 Teulire <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) ) *
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment