TernaryPoint.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB.  All rights reserved.
00003 **
00004 ** This file is part of the KD Chart library.
00005 **
00006 ** Licensees holding valid commercial KD Chart licenses may use this file in
00007 ** accordance with the KD Chart Commercial License Agreement provided with
00008 ** the Software.
00009 **
00010 **
00011 ** This file may be distributed and/or modified under the terms of the
00012 ** GNU General Public License version 2 and version 3 as published by the
00013 ** Free Software Foundation and appearing in the file LICENSE.GPL included.
00014 **
00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 **
00018 ** Contact info@kdab.com if any conditions of this licensing are not
00019 ** clear to you.
00020 **
00021 **********************************************************************/
00022 
00023 #include "TernaryPoint.h"
00024 #include "TernaryConstants.h"
00025 
00026 #include <limits>
00027 
00028 #include <QChar>
00029 #include <QTextStream>
00030 
00031 TernaryPoint::TernaryPoint()
00032     : m_a( -1.0 )
00033     , m_b( -1.0 )
00034 {
00035     Q_ASSERT( !isValid() );
00036 }
00037 
00038 TernaryPoint::TernaryPoint( double a, double b )
00039     : m_a( -1.0 )
00040     , m_b( -1.0 )
00041 {
00042     set( a, b );
00043 }
00044 
00045 void TernaryPoint::set( double a, double b )
00046 {
00047     if ( a >= 0.0 && a <= 1.0
00048          && b >= 0.0 && b <= 1.0
00049          && 1.0 - a - b >= -2.0 * std::numeric_limits<double>::epsilon() ) {
00050         m_a = a;
00051         m_b = b;
00052         Q_ASSERT( isValid() ); // more a test for isValid
00053     } else {
00054         m_a = -1.0;
00055         m_b = -1.0;
00056         Q_ASSERT( ! isValid() );
00057     }
00058 }
00059 
00060 bool TernaryPoint::isValid() const
00061 {
00062     return
00063         m_a >= 0.0 && m_a <= 1.0
00064         && m_b >= 0.0 && m_b <= 1.0
00065         && 1.0 - m_a + m_b >= - std::numeric_limits<double>::epsilon();
00066 }
00067 
00068 QDebug operator<<( QDebug stream, const TernaryPoint& point )
00069 {
00070     QString string;
00071     QTextStream text( &string );
00072     text << "[TernaryPoint: ";
00073     if ( point.isValid() ) {
00074         text.setFieldWidth( 2 );
00075         text.setPadChar( QLatin1Char( '0' ) );
00076         text << ( int ) ( point.a() * 100.0 ) << "%|"
00077              << ( int ) ( point.b() * 100.0 ) << "%|"
00078              << ( int ) ( point.c() * 100.0 ) << "%]";
00079     } else {
00080         text << "a=" << point.a() << " - b=" << point.b() << " - INVALID]";
00081     }
00082     stream << string;
00083     return stream;
00084 }
00085 
00086 QPointF translate( const TernaryPoint& point )
00087 {
00088     if ( point.isValid() ) {
00089         // the position is calculated by
00090         // - first moving along the B-C line to the function that b
00091         //   selects
00092         // - then traversing the selected function until we meet with
00093         //   the function that A selects (which is a parallel of the B-C
00094         //   line)
00095         QPointF bPosition( 1.0 - point.b(), 0.0 );
00096         QPointF aPosition( point.a() * AxisVector_C_A );
00097         QPointF result( bPosition + aPosition );
00098         return result;
00099     } else {
00100         qWarning() << "TernaryPoint::translate(TernaryPoint): cannot translate invalid ternary points:"
00101                    << point;
00102         return QPointF();
00103     }
00104 }