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 }