BlosSOM
Interactive dimensionality reduction on large datasets (EmbedSOM and FLOWER combined)
graph_layout.cpp
Go to the documentation of this file.
1/* This file is part of BlosSOM.
2 *
3 * Copyright (C) 2021 Mirek Kratochvil
4 * Sona Molnarova
5 *
6 * BlosSOM is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
9 * any later version.
10 *
11 * BlosSOM is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * BlosSOM. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "graph_layout.h"
21
22// TODO: parametrize the constants
23
24void
26 bool vert_pressed,
27 int vert_ind,
28 LandmarkModel &lm,
29 float time)
30{
31 auto &vertices = lm.lodim_vertices;
32 const auto &edges = lm.edges;
33 const auto &edge_lengths = lm.edge_lengths;
34
35 if (time > 0.05)
36 time = 0.05;
37 // check if data is m'kay
38 if (data.velocities.size() != vertices.size())
39 data.velocities.resize(vertices.size(), glm::vec2(0, 0));
40 if (data.forces.size() != vertices.size())
41 data.forces.resize(vertices.size());
42
43 // clean up the forces
44 for (auto &v : data.forces)
45 v = glm::vec2(0, 0);
46
47 // add repulsive forces
48 for (size_t i = 1; i < vertices.size(); ++i)
49 for (size_t j = 0; j < i; ++j) {
50 auto d = vertices[j] - vertices[i];
51 float q = exp(-glm::length(d) * 3) * 1000 * time;
52 data.forces[i] += -q * d;
53 data.forces[j] += q * d;
54 }
55
56 // add compulsive forces
57 for (size_t i = 0; i < edges.size(); ++i) {
58 auto [p1, p2] = edges[i];
59 auto d = vertices[p2] - vertices[p1];
60 auto q = (edge_lengths[i] - glm::length(d)) * 1000 * time;
61 data.forces[p1] += -q * d;
62 data.forces[p2] += q * d;
63 }
64
65 // update velocities and positions
66 auto slowdown = pow(0.1f, time);
67 for (size_t i = 0; i < vertices.size(); ++i) {
68 if (vert_pressed && vert_ind == i)
69 continue;
70
71 data.velocities[i] += data.forces[i] * time;
72 vertices[i] += data.velocities[i] * time;
73 data.velocities[i] *= slowdown;
74 }
75
76 lm.touch();
77}
void graph_layout_step(GraphLayoutData &data, bool vert_pressed, int vert_ind, LandmarkModel &lm, float time)
One iteration step of the landmark layouting algorithm.
void touch()
Make the cache dirty.
Definition: dirty.h:43
Data for landmark graph layouting algorithm using forces.
Definition: graph_layout.h:35
std::vector< glm::vec2 > forces
Forces of 2D landmarks.
Definition: graph_layout.h:39
std::vector< glm::vec2 > velocities
Velocities of 2D landmarks.
Definition: graph_layout.h:37
Model of the high- and low-dimensional landmarks.
std::vector< glm::vec2 > lodim_vertices
Array storing two-dimensional landmark coordinates.
std::vector< float > edge_lengths
Lengths of all edges.
std::vector< std::pair< size_t, size_t > > edges
Array of vertex ID pairs.