# TernaryPoint.cpp

Go to the documentation of this file.

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