1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "onedimensionalcluster.h"
27
28 #include <utils/algorithm.h>
29
30 #include <QDebug>
31
32 namespace QmlDesigner {
33
sum(const QList<double> & list)34 double sum(const QList<double> & list)
35 {
36 double sum = 0.0;
37 for (auto iterator = list.constBegin(); iterator != list.constEnd(); ++iterator)
38 {
39 sum += *iterator;
40 }
41
42 return sum;
43 }
44
OneDimensionalCluster(const QList<double> & coordinateList)45 OneDimensionalCluster::OneDimensionalCluster(const QList<double> & coordinateList )
46 : m_coordinateList(coordinateList)
47 {
48 }
49
mean() const50 double OneDimensionalCluster::mean() const
51 {
52 Q_ASSERT(!m_coordinateList.isEmpty());
53
54 if (m_coordinateList.size() == 1)
55 {
56 return m_coordinateList.constFirst();
57 }
58
59 return sum(m_coordinateList) / m_coordinateList.size();
60 }
61
constFirst() const62 double OneDimensionalCluster::constFirst() const
63 {
64 Q_ASSERT(!m_coordinateList.isEmpty());
65
66 return m_coordinateList.constFirst();
67 }
68
createOneDimensionalClusterList(const QList<double> & oneDimensionalCoordinateList)69 QList<OneDimensionalCluster> OneDimensionalCluster::createOneDimensionalClusterList(const QList<double> & oneDimensionalCoordinateList)
70 {
71 QList<OneDimensionalCluster> oneDimensionalClusterList;
72 foreach (double coordinate, oneDimensionalCoordinateList)
73 {
74 QList<double> initialList;
75 initialList.append(coordinate);
76 OneDimensionalCluster cluster(initialList);
77 oneDimensionalClusterList.append(initialList);
78 }
79
80 return oneDimensionalClusterList;
81 }
82
reduceOneDimensionalClusterList(const QList<OneDimensionalCluster> & unreducedClusterList,double maximumDistance)83 QList<OneDimensionalCluster> OneDimensionalCluster::reduceOneDimensionalClusterList(const QList<OneDimensionalCluster> & unreducedClusterList, double maximumDistance)
84 {
85 if (unreducedClusterList.size() < 2)
86 return unreducedClusterList;
87
88
89 QList<OneDimensionalCluster> workingList(unreducedClusterList);
90 QList<OneDimensionalCluster> reducedList;
91 while (true)
92 {
93 Utils::sort(workingList);
94 reducedList.clear();
95 bool clusterMerged = false;
96
97 for (int i = 0, n = workingList.size(); i != n; ) {
98
99 OneDimensionalCluster currentCluster = workingList.at(i);
100 if (i + 1 < n) {
101 OneDimensionalCluster nextCluster = workingList.at(i + 1);
102 if ((nextCluster.mean() - currentCluster.mean()) < maximumDistance)
103 {
104 reducedList.append(currentCluster + nextCluster);
105 ++i;
106 clusterMerged = true;
107 }
108 else
109 {
110 reducedList.append(currentCluster);
111 }
112 }
113 else
114 {
115 reducedList.append(currentCluster);
116 break;
117 }
118
119 }
120
121 workingList = reducedList;
122
123 if (clusterMerged == false)
124 break;
125 }
126
127
128 return reducedList;
129 }
130
reduceLines(const QList<double> & oneDimensionalCoordinateList,double maximumDistance)131 QList<double> OneDimensionalCluster::reduceLines(const QList<double> & oneDimensionalCoordinateList, double maximumDistance)
132 {
133 QList<OneDimensionalCluster> clusterList(createOneDimensionalClusterList(oneDimensionalCoordinateList));
134 clusterList = reduceOneDimensionalClusterList(clusterList, maximumDistance);
135
136 QList<double> lineList;
137 foreach (const OneDimensionalCluster &cluster, clusterList)
138 lineList.append(cluster.constFirst());
139
140 return lineList;
141 }
142
143 }
144