Advertisement
Guest User

lab1_inva

a guest
Feb 18th, 2020
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.50 KB | None | 0 0
  1. #pragma once
  2. #include <QWidget>
  3. #include <QPaintEvent>
  4. #include <QPainter>
  5. #include <QKeyEvent>
  6. #include <QMouseEvent>
  7. #include <QPen>
  8. #include <vector>
  9. #include <math.h>
  10.  
  11. struct BasePoint
  12. {
  13. int x, y;
  14. QColor color;
  15.  
  16. BasePoint(int _x, int _y, QColor _color)
  17. :x(_x), y(_y), color(_color)
  18. {
  19. }
  20. };
  21.  
  22. struct Cluster;
  23.  
  24. struct KPoint : public BasePoint
  25. {
  26. Cluster *parentCluster;
  27.  
  28. KPoint(int _x = 0, int _y = 0, QColor _color = QColor(Qt::black))
  29. : BasePoint(_x, _y, _color), parentCluster(nullptr)
  30. {
  31. }
  32. };
  33.  
  34. struct Cluster : public BasePoint
  35. {
  36. std::vector<KPoint*> kpoints;
  37. int minx, miny, maxx, maxy;
  38.  
  39. Cluster(int _x, int _y, QColor _color)
  40. : BasePoint(_x, _y, _color)
  41. {
  42. }
  43. };
  44.  
  45. class KMeans : public QWidget
  46. {
  47. std::vector<KPoint*> kpoints;
  48. std::vector<Cluster*> clusters;
  49. int pointRadius;
  50. int clusterCenterRadius;
  51.  
  52. public:
  53. KMeans(QWidget* parent = 0) :
  54. QWidget(parent), pointRadius(3), clusterCenterRadius(6)
  55. {
  56. genPoints(200);
  57. }
  58.  
  59. void genPoints(int nr)
  60. {
  61. while (nr--)
  62. kpoints.push_back(new KPoint(rand() % width(), rand() % height()));
  63. }
  64.  
  65. void paintEvent(QPaintEvent *e)
  66. {
  67. QPainter painter(this);
  68.  
  69. painter.setPen(Qt::black);
  70. for (KPoint* &p : kpoints)
  71. {
  72. QColor pointColor;
  73. if (p->parentCluster)
  74. {
  75. pointColor = p->parentCluster->color;
  76. painter.setPen(pointColor);
  77. painter.drawLine(p->x, p->y, p->parentCluster->x, p->parentCluster->y);
  78. }
  79. else
  80. {
  81. pointColor = Qt::black;
  82. }
  83. painter.setPen(Qt::black);
  84. painter.setBrush(pointColor);
  85. painter.drawEllipse(p->x - pointRadius, p->y - pointRadius, pointRadius * 2, pointRadius * 2);
  86. }
  87.  
  88. for (auto &c : clusters)
  89. {
  90. painter.setBrush(c->color);
  91. painter.drawEllipse(c->x - clusterCenterRadius, c->y - clusterCenterRadius, clusterCenterRadius * 2, clusterCenterRadius * 2);
  92. }
  93. }
  94.  
  95. void mousePressEvent(QMouseEvent *e)
  96. {
  97. switch (e->button())
  98. {
  99. case Qt::LeftButton:
  100.  
  101. //...
  102.  
  103. clusters.push_back(new Cluster(e->x(), e->y(), Qt::red));
  104. iterate();
  105.  
  106. update(); //redesenarea ferestrei (se apeleaza paintEvent())
  107. break;
  108. case Qt::RightButton:
  109.  
  110. deleteCluster(e->x(), e->y());
  111. iterate();
  112.  
  113. update();
  114. break;
  115. }
  116. }
  117.  
  118. void deleteCluster(int x, int y) {
  119. Cluster *cdel;
  120. for (auto c : clusters) {
  121. if (c->x == x && c->y == y) {
  122. cdel = c;
  123. }
  124. }
  125. clusters.erase(std::remove(clusters.begin(), clusters.end(), cdel), clusters.end());
  126. }
  127.  
  128. void keyPressEvent(QKeyEvent *e)
  129. {
  130. switch (e->key())
  131. {
  132.  
  133. case Qt::Key_Space:
  134.  
  135. clearCenters();
  136. iterate();
  137. updateCenters();
  138. update();
  139. break;
  140.  
  141. case Qt::Key_Escape:
  142. this->close();
  143. };
  144. }
  145.  
  146. void iterate() {
  147. for (auto p : kpoints) {
  148. float min = FLT_MAX;
  149. Cluster* minCLuster;
  150. for (auto c : clusters) {
  151. float temp = calculateDistance(p, c);
  152. if (temp< min) {
  153. minCLuster = c;
  154. min = temp;
  155. }
  156. }
  157. minCLuster->kpoints.push_back(p);
  158. p->parentCluster = minCLuster;
  159. }
  160. }
  161.  
  162. void clearCenters() {
  163. for (auto c : clusters) {
  164. c->kpoints.clear();
  165. }
  166. }
  167.  
  168. void updateCenters() {
  169. int sumx = 0;
  170. int sumy = 0;
  171. for (auto c : clusters) {
  172. for (auto k : c->kpoints) {
  173. sumx += k->x;
  174. sumy += k->y;
  175. }
  176. c->x = sumx / c->kpoints.size();
  177. c->y = sumy / c->kpoints.size();
  178. sumx = 0;
  179. sumy = 0;
  180. }
  181. }
  182.  
  183. float calculateDistance(KPoint *p, Cluster *c) {
  184. return (p->x - c->x)*(p->x - c->x) + (p->y - c->y)*(p->y - c->y);
  185. }
  186.  
  187. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement