Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
DTreeForceTypes.h
Go to the documentation of this file.
1
29#pragma once
30
31#include <cmath>
32#include <type_traits>
33
34namespace ogdf {
35namespace energybased {
36namespace dtree {
37
38template<int Dim>
39inline typename std::enable_if<Dim != 2, double>::type computeDeltaAndDistance(const double a[Dim],
40 const double b[Dim], double delta[Dim]) {
41 // distance var
42 double dist = 0;
43
44 // for all dim
45 for (int d = 0; d < Dim; d++) {
46 // delta in d dim
47 delta[d] = a[d] - b[d];
48
49 // squared distance sum
50 dist += delta[d] * delta[d];
51 }
52
53 // distance square root
54 return sqrt(dist);
55}
56
57template<int Dim>
58inline typename std::enable_if<Dim == 2, double>::type computeDeltaAndDistance(const double a[Dim],
59 const double b[Dim], double delta[Dim]) {
60 // delta in d dim
61 delta[0] = a[0] - b[0];
62 delta[1] = a[1] - b[1];
63
64 // distance square root
65 return sqrt(delta[0] * delta[0] + delta[1] * delta[1]);
66}
67
68template<int Dim, int K>
69inline typename std::enable_if<Dim != 2 || (K != 1 && K != 2), void>::type RepForceFunctionNewton(
70 double dist, double& force, double& force_prime) {
71 // distance square root
72 dist = dist + 0.1;
73
74 double t = dist;
75 for (int i = 1; i < K; i++) {
76 t *= dist;
77 }
78
79 force = 1.0 / (t);
80 force_prime = (double)(K) / (t * dist);
81}
82
83template<int Dim, int K>
84inline typename std::enable_if<Dim == 2 && K == 2, void>::type RepForceFunctionNewton(double dist,
85 double& force, double& force_prime) {
86 // distance square root
87 dist = dist + 0.1;
88 force_prime = 2.0 / (dist * dist * dist);
89 force = force_prime * dist * 0.5;
90}
91
92template<int Dim, int K>
93inline typename std::enable_if<Dim == 2 && K == 1, void>::type RepForceFunctionNewton(double dist,
94 double& force, double& force_prime) {
95 // distance square root
96 dist = dist + 0.1;
97 force_prime = 1.0 / (dist * dist);
98 force = 1.0 / (dist);
99}
100
101template<int Dim>
102inline void AttrForceFunctionLog(double dist, double& force, double& force_prime) {
103 // distance square root
104 force = log(dist / 1.0);
105 force_prime = 1.0 / dist;
106}
107
108template<int Dim, int K>
109inline typename std::enable_if<Dim != 2 || (K != 1 && K != 2), void>::type AttrForceFunctionPow(
110 double dist, double& force, double& force_prime) {
111 // distance square root
112 dist = dist + 0.1;
113
114 double t = dist;
115 for (int i = 1; i < K; i++) {
116 t *= dist;
117 }
118
119 force = t;
120 force_prime = (double)(K) * (t / dist);
121}
122
123template<int Dim, int K>
124inline typename std::enable_if<Dim == 2 && K == 2, void>::type AttrForceFunctionPow(double dist,
125 double& force, double& force_prime) {
126 // distance square root
127 dist = dist + 0.1;
128
129 force = dist * dist;
130 force_prime = 2.0 * dist;
131}
132
133template<int Dim, int K>
134inline typename std::enable_if<Dim == 2 && K == 1, void>::type AttrForceFunctionPow(double dist,
135 double& force, double& force_prime) {
136 // distance square root
137 dist = dist + 0.1;
138
139 force = dist;
140 force_prime = 1.0;
141}
142
143#if 0
144template<int Dim>
145inline void RepForceFunctionInvGauss(const double a[Dim], const double b[Dim], double result[Dim])
146{
147 // the range of the repulsive force
148 const double force_range = 10.0;
149
150 // the amount of repulsive force
151 const double force_amount = 20.0;
152
153 // vector from b to a
154 double delta[Dim];
155
156 // distance var
157 double dist = 0;
158
159 // for all dim
160 for (int d = 0; d < Dim; d++) {
161 // delta in d dim
162 delta[d] = a[d] - b[d];
163
164 // squared distance sum
165 dist += delta[d] * delta[d];
166 }
167
168 // distance square root
169 dist = sqrt(dist);
170
171 // force function
172 double f = (exp(- (dist * dist) / force_range ) * force_amount);
173# if 0
174 double f = exp(-dist * dist * 0.01) * 10.0) / dist;
175# endif
176
177
178 // compute the force vector for each dim
179 for (int d = 0; d < Dim; d++) {
180 result[d] = delta[d] * f/dist;
181 };
182}
183#endif
184
185}
186}
187}
std::enable_if< Dim!=2, double >::type computeDeltaAndDistance(const double a[Dim], const double b[Dim], double delta[Dim])
std::enable_if< Dim!=2||(K!=1 &&K!=2), void >::type AttrForceFunctionPow(double dist, double &force, double &force_prime)
void AttrForceFunctionLog(double dist, double &force, double &force_prime)
std::enable_if< Dim!=2||(K!=1 &&K!=2), void >::type RepForceFunctionNewton(double dist, double &force, double &force_prime)
The namespace for all OGDF objects.