File indexing completed on 2024-05-12 16:30:46

0001 /* This file is part of the KDE project
0002    Copyright (C) 2002 Lennart Kudling <kudling@kde.org>
0003    Copyright (C) 2004 Laurent Montel <montel@kde.org>
0004    Copyright (C) 2005-2006 Thomas Zander <zander@kde.org>
0005    Copyright (C) 2006 Tim Beaulen <tbscope@gmail.com>
0006    Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
0007 
0008    This library is free software; you can redistribute it and/or
0009    modify it under the terms of the GNU Library General Public
0010    License as published by the Free Software Foundation; either
0011    version 2 of the License, or (at your option) any later version.
0012 
0013    This library is distributed in the hope that it will be useful,
0014    but WITHOUT ANY WARRANTY; without even the implied warranty of
0015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016    Library General Public License for more details.
0017 
0018    You should have received a copy of the GNU Library General Public License
0019    along with this library; see the file COPYING.LIB.  If not, write to
0020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022 */
0023 
0024 #include "KarbonGlobal.h"
0025 #include <math.h>
0026 
0027 int KarbonGlobal::binomialCoeff(unsigned n, unsigned k)
0028 {
0029     return
0030         static_cast<int>(
0031             0.5 +
0032             exp(
0033                 factorialLn(n) -
0034                 factorialLn(k) -
0035                 factorialLn(n - k)));
0036 }
0037 
0038 qreal KarbonGlobal::factorialLn(unsigned n)
0039 {
0040     const unsigned cacheSize = 100;
0041 
0042     // A static array is initialized to zero.
0043     static qreal cache[ cacheSize ];
0044 
0045 
0046     if (n <= 1)
0047         return 0.0;
0048 
0049     if (n <= cacheSize - 1) {
0050         return cache[ n ]
0051                ? cache[ n ]
0052                : (cache[ n ] = gammaLn(n + 1.0));
0053     } else {
0054         return gammaLn(n + 1.0);
0055     }
0056 }
0057 
0058 qreal KarbonGlobal::gammaLn(qreal x)
0059 {
0060     static const qreal coeff[ 6 ] = {
0061         76.18009172947146,
0062         -86.50532032941677,
0063         24.01409824083091,
0064         -1.231739572450155,
0065         0.1208650973866179e-2,
0066         -0.5395239384953e-5
0067     };
0068 
0069     qreal y = x;
0070 
0071     qreal tmp = x + 5.5;
0072     tmp -= (x + 0.5) * log(tmp);
0073 
0074     qreal ser = 1.000000000190015;
0075 
0076     for (int i = 0; i < 5; ++i) {
0077         ser += coeff[ i ] / ++y;
0078     }
0079 
0080     return -tmp + log(2.5066282746310005 * ser / x);
0081 }
0082 
0083 qreal KarbonGlobal::scalarProduct(const QPointF &p1, const QPointF &p2)
0084 {
0085     return p1.x() * p2.x() + p1.y() * p2.y();
0086 }
0087 
0088 bool KarbonGlobal::pointsAreNear(const QPointF &p1, const QPointF &p2, qreal range)
0089 {
0090     return (p2.x() >= p1.x() - range && p2.x() <= p1.x() + range && p2.y() >= p1.y() - range && p2.y() <= p1.y() + range);
0091 }
0092 
0093 QPointF KarbonGlobal::crossProduct(const QPointF &v1, const QPointF &v2)
0094 {
0095     return QPointF(v1.x() * v2.y(), -v1.y()*v2.x());
0096 }