annotate DEPENDENCIES/generic/include/boost/graph/topology.hpp @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2009 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Distributed under the Boost Software License, Version 1.0.
Chris@16 4 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Jeremiah Willcock
Chris@16 8 // Douglas Gregor
Chris@16 9 // Andrew Lumsdaine
Chris@16 10 #ifndef BOOST_GRAPH_TOPOLOGY_HPP
Chris@16 11 #define BOOST_GRAPH_TOPOLOGY_HPP
Chris@16 12
Chris@16 13 #include <boost/config/no_tr1/cmath.hpp>
Chris@16 14 #include <cmath>
Chris@16 15 #include <boost/random/uniform_01.hpp>
Chris@16 16 #include <boost/random/linear_congruential.hpp>
Chris@16 17 #include <boost/math/constants/constants.hpp> // For root_two
Chris@16 18 #include <boost/algorithm/minmax.hpp>
Chris@16 19 #include <boost/config.hpp> // For BOOST_STATIC_CONSTANT
Chris@16 20 #include <boost/math/special_functions/hypot.hpp>
Chris@16 21
Chris@16 22 // Classes and concepts to represent points in a space, with distance and move
Chris@16 23 // operations (used for Gurson-Atun layout), plus other things like bounding
Chris@16 24 // boxes used for other layout algorithms.
Chris@16 25
Chris@16 26 namespace boost {
Chris@16 27
Chris@16 28 /***********************************************************
Chris@16 29 * Topologies *
Chris@16 30 ***********************************************************/
Chris@16 31 template<std::size_t Dims>
Chris@16 32 class convex_topology
Chris@16 33 {
Chris@16 34 public: // For VisualAge C++
Chris@16 35 struct point
Chris@16 36 {
Chris@16 37 BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims);
Chris@16 38 point() { }
Chris@16 39 double& operator[](std::size_t i) {return values[i];}
Chris@16 40 const double& operator[](std::size_t i) const {return values[i];}
Chris@16 41
Chris@16 42 private:
Chris@16 43 double values[Dims];
Chris@16 44 };
Chris@16 45
Chris@16 46 public: // For VisualAge C++
Chris@16 47 struct point_difference
Chris@16 48 {
Chris@16 49 BOOST_STATIC_CONSTANT(std::size_t, dimensions = Dims);
Chris@16 50 point_difference() {
Chris@16 51 for (std::size_t i = 0; i < Dims; ++i) values[i] = 0.;
Chris@16 52 }
Chris@16 53 double& operator[](std::size_t i) {return values[i];}
Chris@16 54 const double& operator[](std::size_t i) const {return values[i];}
Chris@16 55
Chris@16 56 friend point_difference operator+(const point_difference& a, const point_difference& b) {
Chris@16 57 point_difference result;
Chris@16 58 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 59 result[i] = a[i] + b[i];
Chris@16 60 return result;
Chris@16 61 }
Chris@16 62
Chris@16 63 friend point_difference& operator+=(point_difference& a, const point_difference& b) {
Chris@16 64 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 65 a[i] += b[i];
Chris@16 66 return a;
Chris@16 67 }
Chris@16 68
Chris@16 69 friend point_difference operator-(const point_difference& a) {
Chris@16 70 point_difference result;
Chris@16 71 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 72 result[i] = -a[i];
Chris@16 73 return result;
Chris@16 74 }
Chris@16 75
Chris@16 76 friend point_difference operator-(const point_difference& a, const point_difference& b) {
Chris@16 77 point_difference result;
Chris@16 78 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 79 result[i] = a[i] - b[i];
Chris@16 80 return result;
Chris@16 81 }
Chris@16 82
Chris@16 83 friend point_difference& operator-=(point_difference& a, const point_difference& b) {
Chris@16 84 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 85 a[i] -= b[i];
Chris@16 86 return a;
Chris@16 87 }
Chris@16 88
Chris@16 89 friend point_difference operator*(const point_difference& a, const point_difference& b) {
Chris@16 90 point_difference result;
Chris@16 91 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 92 result[i] = a[i] * b[i];
Chris@16 93 return result;
Chris@16 94 }
Chris@16 95
Chris@16 96 friend point_difference operator*(const point_difference& a, double b) {
Chris@16 97 point_difference result;
Chris@16 98 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 99 result[i] = a[i] * b;
Chris@16 100 return result;
Chris@16 101 }
Chris@16 102
Chris@16 103 friend point_difference operator*(double a, const point_difference& b) {
Chris@16 104 point_difference result;
Chris@16 105 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 106 result[i] = a * b[i];
Chris@16 107 return result;
Chris@16 108 }
Chris@16 109
Chris@16 110 friend point_difference operator/(const point_difference& a, const point_difference& b) {
Chris@16 111 point_difference result;
Chris@16 112 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 113 result[i] = (b[i] == 0.) ? 0. : a[i] / b[i];
Chris@16 114 return result;
Chris@16 115 }
Chris@16 116
Chris@16 117 friend double dot(const point_difference& a, const point_difference& b) {
Chris@16 118 double result = 0;
Chris@16 119 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 120 result += a[i] * b[i];
Chris@16 121 return result;
Chris@16 122 }
Chris@16 123
Chris@16 124 private:
Chris@16 125 double values[Dims];
Chris@16 126 };
Chris@16 127
Chris@16 128 public:
Chris@16 129 typedef point point_type;
Chris@16 130 typedef point_difference point_difference_type;
Chris@16 131
Chris@16 132 double distance(point a, point b) const
Chris@16 133 {
Chris@16 134 double dist = 0.;
Chris@16 135 for (std::size_t i = 0; i < Dims; ++i) {
Chris@16 136 double diff = b[i] - a[i];
Chris@16 137 dist = boost::math::hypot(dist, diff);
Chris@16 138 }
Chris@16 139 // Exact properties of the distance are not important, as long as
Chris@16 140 // < on what this returns matches real distances; l_2 is used because
Chris@16 141 // Fruchterman-Reingold also uses this code and it relies on l_2.
Chris@16 142 return dist;
Chris@16 143 }
Chris@16 144
Chris@16 145 point move_position_toward(point a, double fraction, point b) const
Chris@16 146 {
Chris@16 147 point result;
Chris@16 148 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 149 result[i] = a[i] + (b[i] - a[i]) * fraction;
Chris@16 150 return result;
Chris@16 151 }
Chris@16 152
Chris@16 153 point_difference difference(point a, point b) const {
Chris@16 154 point_difference result;
Chris@16 155 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 156 result[i] = a[i] - b[i];
Chris@16 157 return result;
Chris@16 158 }
Chris@16 159
Chris@16 160 point adjust(point a, point_difference delta) const {
Chris@16 161 point result;
Chris@16 162 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 163 result[i] = a[i] + delta[i];
Chris@16 164 return result;
Chris@16 165 }
Chris@16 166
Chris@16 167 point pointwise_min(point a, point b) const {
Chris@16 168 BOOST_USING_STD_MIN();
Chris@16 169 point result;
Chris@16 170 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 171 result[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION (a[i], b[i]);
Chris@16 172 return result;
Chris@16 173 }
Chris@16 174
Chris@16 175 point pointwise_max(point a, point b) const {
Chris@16 176 BOOST_USING_STD_MAX();
Chris@16 177 point result;
Chris@16 178 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 179 result[i] = max BOOST_PREVENT_MACRO_SUBSTITUTION (a[i], b[i]);
Chris@16 180 return result;
Chris@16 181 }
Chris@16 182
Chris@16 183 double norm(point_difference delta) const {
Chris@16 184 double n = 0.;
Chris@16 185 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 186 n = boost::math::hypot(n, delta[i]);
Chris@16 187 return n;
Chris@16 188 }
Chris@16 189
Chris@16 190 double volume(point_difference delta) const {
Chris@16 191 double n = 1.;
Chris@16 192 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 193 n *= delta[i];
Chris@16 194 return n;
Chris@16 195 }
Chris@16 196
Chris@16 197 };
Chris@16 198
Chris@16 199 template<std::size_t Dims,
Chris@16 200 typename RandomNumberGenerator = minstd_rand>
Chris@16 201 class hypercube_topology : public convex_topology<Dims>
Chris@16 202 {
Chris@16 203 typedef uniform_01<RandomNumberGenerator, double> rand_t;
Chris@16 204
Chris@16 205 public:
Chris@16 206 typedef typename convex_topology<Dims>::point_type point_type;
Chris@16 207 typedef typename convex_topology<Dims>::point_difference_type point_difference_type;
Chris@16 208
Chris@16 209 explicit hypercube_topology(double scaling = 1.0)
Chris@16 210 : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)),
Chris@16 211 scaling(scaling)
Chris@16 212 { }
Chris@16 213
Chris@16 214 hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
Chris@16 215 : gen_ptr(), rand(new rand_t(gen)), scaling(scaling) { }
Chris@16 216
Chris@16 217 point_type random_point() const
Chris@16 218 {
Chris@16 219 point_type p;
Chris@16 220 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 221 p[i] = (*rand)() * scaling;
Chris@16 222 return p;
Chris@16 223 }
Chris@16 224
Chris@16 225 point_type bound(point_type a) const
Chris@16 226 {
Chris@16 227 BOOST_USING_STD_MIN();
Chris@16 228 BOOST_USING_STD_MAX();
Chris@16 229 point_type p;
Chris@16 230 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 231 p[i] = min BOOST_PREVENT_MACRO_SUBSTITUTION (scaling, max BOOST_PREVENT_MACRO_SUBSTITUTION (-scaling, a[i]));
Chris@16 232 return p;
Chris@16 233 }
Chris@16 234
Chris@16 235 double distance_from_boundary(point_type a) const
Chris@16 236 {
Chris@16 237 BOOST_USING_STD_MIN();
Chris@16 238 BOOST_USING_STD_MAX();
Chris@16 239 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 240 using std::abs;
Chris@16 241 #endif
Chris@16 242 BOOST_STATIC_ASSERT (Dims >= 1);
Chris@16 243 double dist = abs(scaling - a[0]);
Chris@16 244 for (std::size_t i = 1; i < Dims; ++i)
Chris@16 245 dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(scaling - a[i]));
Chris@16 246 return dist;
Chris@16 247 }
Chris@16 248
Chris@16 249 point_type center() const {
Chris@16 250 point_type result;
Chris@16 251 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 252 result[i] = scaling * .5;
Chris@16 253 return result;
Chris@16 254 }
Chris@16 255
Chris@16 256 point_type origin() const {
Chris@16 257 point_type result;
Chris@16 258 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 259 result[i] = 0;
Chris@16 260 return result;
Chris@16 261 }
Chris@16 262
Chris@16 263 point_difference_type extent() const {
Chris@16 264 point_difference_type result;
Chris@16 265 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 266 result[i] = scaling;
Chris@16 267 return result;
Chris@16 268 }
Chris@16 269
Chris@16 270 private:
Chris@16 271 shared_ptr<RandomNumberGenerator> gen_ptr;
Chris@16 272 shared_ptr<rand_t> rand;
Chris@16 273 double scaling;
Chris@16 274 };
Chris@16 275
Chris@16 276 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 277 class square_topology : public hypercube_topology<2, RandomNumberGenerator>
Chris@16 278 {
Chris@16 279 typedef hypercube_topology<2, RandomNumberGenerator> inherited;
Chris@16 280
Chris@16 281 public:
Chris@16 282 explicit square_topology(double scaling = 1.0) : inherited(scaling) { }
Chris@16 283
Chris@16 284 square_topology(RandomNumberGenerator& gen, double scaling = 1.0)
Chris@16 285 : inherited(gen, scaling) { }
Chris@16 286 };
Chris@16 287
Chris@16 288 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 289 class rectangle_topology : public convex_topology<2>
Chris@16 290 {
Chris@16 291 typedef uniform_01<RandomNumberGenerator, double> rand_t;
Chris@16 292
Chris@16 293 public:
Chris@16 294 rectangle_topology(double left, double top, double right, double bottom)
Chris@16 295 : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)),
Chris@16 296 left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)),
Chris@16 297 top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)),
Chris@16 298 right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)),
Chris@16 299 bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)) { }
Chris@16 300
Chris@16 301 rectangle_topology(RandomNumberGenerator& gen, double left, double top, double right, double bottom)
Chris@16 302 : gen_ptr(), rand(new rand_t(gen)),
Chris@16 303 left(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)),
Chris@16 304 top(std::min BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)),
Chris@16 305 right(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (left, right)),
Chris@16 306 bottom(std::max BOOST_PREVENT_MACRO_SUBSTITUTION (top, bottom)) { }
Chris@16 307
Chris@16 308 typedef typename convex_topology<2>::point_type point_type;
Chris@16 309 typedef typename convex_topology<2>::point_difference_type point_difference_type;
Chris@16 310
Chris@16 311 point_type random_point() const
Chris@16 312 {
Chris@16 313 point_type p;
Chris@16 314 p[0] = (*rand)() * (right - left) + left;
Chris@16 315 p[1] = (*rand)() * (bottom - top) + top;
Chris@16 316 return p;
Chris@16 317 }
Chris@16 318
Chris@16 319 point_type bound(point_type a) const
Chris@16 320 {
Chris@16 321 BOOST_USING_STD_MIN();
Chris@16 322 BOOST_USING_STD_MAX();
Chris@16 323 point_type p;
Chris@16 324 p[0] = min BOOST_PREVENT_MACRO_SUBSTITUTION (right, max BOOST_PREVENT_MACRO_SUBSTITUTION (left, a[0]));
Chris@16 325 p[1] = min BOOST_PREVENT_MACRO_SUBSTITUTION (bottom, max BOOST_PREVENT_MACRO_SUBSTITUTION (top, a[1]));
Chris@16 326 return p;
Chris@16 327 }
Chris@16 328
Chris@16 329 double distance_from_boundary(point_type a) const
Chris@16 330 {
Chris@16 331 BOOST_USING_STD_MIN();
Chris@16 332 BOOST_USING_STD_MAX();
Chris@16 333 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 334 using std::abs;
Chris@16 335 #endif
Chris@16 336 double dist = abs(left - a[0]);
Chris@16 337 dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(right - a[0]));
Chris@16 338 dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(top - a[1]));
Chris@16 339 dist = min BOOST_PREVENT_MACRO_SUBSTITUTION (dist, abs(bottom - a[1]));
Chris@16 340 return dist;
Chris@16 341 }
Chris@16 342
Chris@16 343 point_type center() const {
Chris@16 344 point_type result;
Chris@16 345 result[0] = (left + right) / 2.;
Chris@16 346 result[1] = (top + bottom) / 2.;
Chris@16 347 return result;
Chris@16 348 }
Chris@16 349
Chris@16 350 point_type origin() const {
Chris@16 351 point_type result;
Chris@16 352 result[0] = left;
Chris@16 353 result[1] = top;
Chris@16 354 return result;
Chris@16 355 }
Chris@16 356
Chris@16 357 point_difference_type extent() const {
Chris@16 358 point_difference_type result;
Chris@16 359 result[0] = right - left;
Chris@16 360 result[1] = bottom - top;
Chris@16 361 return result;
Chris@16 362 }
Chris@16 363
Chris@16 364 private:
Chris@16 365 shared_ptr<RandomNumberGenerator> gen_ptr;
Chris@16 366 shared_ptr<rand_t> rand;
Chris@16 367 double left, top, right, bottom;
Chris@16 368 };
Chris@16 369
Chris@16 370 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 371 class cube_topology : public hypercube_topology<3, RandomNumberGenerator>
Chris@16 372 {
Chris@16 373 typedef hypercube_topology<3, RandomNumberGenerator> inherited;
Chris@16 374
Chris@16 375 public:
Chris@16 376 explicit cube_topology(double scaling = 1.0) : inherited(scaling) { }
Chris@16 377
Chris@16 378 cube_topology(RandomNumberGenerator& gen, double scaling = 1.0)
Chris@16 379 : inherited(gen, scaling) { }
Chris@16 380 };
Chris@16 381
Chris@16 382 template<std::size_t Dims,
Chris@16 383 typename RandomNumberGenerator = minstd_rand>
Chris@16 384 class ball_topology : public convex_topology<Dims>
Chris@16 385 {
Chris@16 386 typedef uniform_01<RandomNumberGenerator, double> rand_t;
Chris@16 387
Chris@16 388 public:
Chris@16 389 typedef typename convex_topology<Dims>::point_type point_type;
Chris@16 390 typedef typename convex_topology<Dims>::point_difference_type point_difference_type;
Chris@16 391
Chris@16 392 explicit ball_topology(double radius = 1.0)
Chris@16 393 : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)),
Chris@16 394 radius(radius)
Chris@16 395 { }
Chris@16 396
Chris@16 397 ball_topology(RandomNumberGenerator& gen, double radius = 1.0)
Chris@16 398 : gen_ptr(), rand(new rand_t(gen)), radius(radius) { }
Chris@16 399
Chris@16 400 point_type random_point() const
Chris@16 401 {
Chris@16 402 point_type p;
Chris@16 403 double dist_sum;
Chris@16 404 do {
Chris@16 405 dist_sum = 0.0;
Chris@16 406 for (std::size_t i = 0; i < Dims; ++i) {
Chris@16 407 double x = (*rand)() * 2*radius - radius;
Chris@16 408 p[i] = x;
Chris@16 409 dist_sum += x * x;
Chris@16 410 }
Chris@16 411 } while (dist_sum > radius*radius);
Chris@16 412 return p;
Chris@16 413 }
Chris@16 414
Chris@16 415 point_type bound(point_type a) const
Chris@16 416 {
Chris@16 417 BOOST_USING_STD_MIN();
Chris@16 418 BOOST_USING_STD_MAX();
Chris@16 419 double r = 0.;
Chris@16 420 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 421 r = boost::math::hypot(r, a[i]);
Chris@16 422 if (r <= radius) return a;
Chris@16 423 double scaling_factor = radius / r;
Chris@16 424 point_type p;
Chris@16 425 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 426 p[i] = a[i] * scaling_factor;
Chris@16 427 return p;
Chris@16 428 }
Chris@16 429
Chris@16 430 double distance_from_boundary(point_type a) const
Chris@16 431 {
Chris@16 432 double r = 0.;
Chris@16 433 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 434 r = boost::math::hypot(r, a[i]);
Chris@16 435 return radius - r;
Chris@16 436 }
Chris@16 437
Chris@16 438 point_type center() const {
Chris@16 439 point_type result;
Chris@16 440 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 441 result[i] = 0;
Chris@16 442 return result;
Chris@16 443 }
Chris@16 444
Chris@16 445 point_type origin() const {
Chris@16 446 point_type result;
Chris@16 447 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 448 result[i] = -radius;
Chris@16 449 return result;
Chris@16 450 }
Chris@16 451
Chris@16 452 point_difference_type extent() const {
Chris@16 453 point_difference_type result;
Chris@16 454 for (std::size_t i = 0; i < Dims; ++i)
Chris@16 455 result[i] = 2. * radius;
Chris@16 456 return result;
Chris@16 457 }
Chris@16 458
Chris@16 459 private:
Chris@16 460 shared_ptr<RandomNumberGenerator> gen_ptr;
Chris@16 461 shared_ptr<rand_t> rand;
Chris@16 462 double radius;
Chris@16 463 };
Chris@16 464
Chris@16 465 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 466 class circle_topology : public ball_topology<2, RandomNumberGenerator>
Chris@16 467 {
Chris@16 468 typedef ball_topology<2, RandomNumberGenerator> inherited;
Chris@16 469
Chris@16 470 public:
Chris@16 471 explicit circle_topology(double radius = 1.0) : inherited(radius) { }
Chris@16 472
Chris@16 473 circle_topology(RandomNumberGenerator& gen, double radius = 1.0)
Chris@16 474 : inherited(gen, radius) { }
Chris@16 475 };
Chris@16 476
Chris@16 477 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 478 class sphere_topology : public ball_topology<3, RandomNumberGenerator>
Chris@16 479 {
Chris@16 480 typedef ball_topology<3, RandomNumberGenerator> inherited;
Chris@16 481
Chris@16 482 public:
Chris@16 483 explicit sphere_topology(double radius = 1.0) : inherited(radius) { }
Chris@16 484
Chris@16 485 sphere_topology(RandomNumberGenerator& gen, double radius = 1.0)
Chris@16 486 : inherited(gen, radius) { }
Chris@16 487 };
Chris@16 488
Chris@16 489 template<typename RandomNumberGenerator = minstd_rand>
Chris@16 490 class heart_topology
Chris@16 491 {
Chris@16 492 // Heart is defined as the union of three shapes:
Chris@16 493 // Square w/ corners (+-1000, -1000), (0, 0), (0, -2000)
Chris@16 494 // Circle centered at (-500, -500) radius 500*sqrt(2)
Chris@16 495 // Circle centered at (500, -500) radius 500*sqrt(2)
Chris@16 496 // Bounding box (-1000, -2000) - (1000, 500*(sqrt(2) - 1))
Chris@16 497
Chris@16 498 struct point
Chris@16 499 {
Chris@16 500 point() { values[0] = 0.0; values[1] = 0.0; }
Chris@16 501 point(double x, double y) { values[0] = x; values[1] = y; }
Chris@16 502
Chris@16 503 double& operator[](std::size_t i) { return values[i]; }
Chris@16 504 double operator[](std::size_t i) const { return values[i]; }
Chris@16 505
Chris@16 506 private:
Chris@16 507 double values[2];
Chris@16 508 };
Chris@16 509
Chris@16 510 bool in_heart(point p) const
Chris@16 511 {
Chris@16 512 #ifndef BOOST_NO_STDC_NAMESPACE
Chris@16 513 using std::abs;
Chris@16 514 #endif
Chris@16 515
Chris@16 516 if (p[1] < abs(p[0]) - 2000) return false; // Bottom
Chris@16 517 if (p[1] <= -1000) return true; // Diagonal of square
Chris@16 518 if (boost::math::hypot(p[0] - -500, p[1] - -500) <= 500. * boost::math::constants::root_two<double>())
Chris@16 519 return true; // Left circle
Chris@16 520 if (boost::math::hypot(p[0] - 500, p[1] - -500) <= 500. * boost::math::constants::root_two<double>())
Chris@16 521 return true; // Right circle
Chris@16 522 return false;
Chris@16 523 }
Chris@16 524
Chris@16 525 bool segment_within_heart(point p1, point p2) const
Chris@16 526 {
Chris@16 527 // Assumes that p1 and p2 are within the heart
Chris@16 528 if ((p1[0] < 0) == (p2[0] < 0)) return true; // Same side of symmetry line
Chris@16 529 if (p1[0] == p2[0]) return true; // Vertical
Chris@16 530 double slope = (p2[1] - p1[1]) / (p2[0] - p1[0]);
Chris@16 531 double intercept = p1[1] - p1[0] * slope;
Chris@16 532 if (intercept > 0) return false; // Crosses between circles
Chris@16 533 return true;
Chris@16 534 }
Chris@16 535
Chris@16 536 typedef uniform_01<RandomNumberGenerator, double> rand_t;
Chris@16 537
Chris@16 538 public:
Chris@16 539 typedef point point_type;
Chris@16 540
Chris@16 541 heart_topology()
Chris@16 542 : gen_ptr(new RandomNumberGenerator), rand(new rand_t(*gen_ptr)) { }
Chris@16 543
Chris@16 544 heart_topology(RandomNumberGenerator& gen)
Chris@16 545 : gen_ptr(), rand(new rand_t(gen)) { }
Chris@16 546
Chris@16 547 point random_point() const
Chris@16 548 {
Chris@16 549 point result;
Chris@16 550 do {
Chris@16 551 result[0] = (*rand)() * (1000 + 1000 * boost::math::constants::root_two<double>()) - (500 + 500 * boost::math::constants::root_two<double>());
Chris@16 552 result[1] = (*rand)() * (2000 + 500 * (boost::math::constants::root_two<double>() - 1)) - 2000;
Chris@16 553 } while (!in_heart(result));
Chris@16 554 return result;
Chris@16 555 }
Chris@16 556
Chris@16 557 // Not going to provide clipping to bounding region or distance from boundary
Chris@16 558
Chris@16 559 double distance(point a, point b) const
Chris@16 560 {
Chris@16 561 if (segment_within_heart(a, b)) {
Chris@16 562 // Straight line
Chris@16 563 return boost::math::hypot(b[0] - a[0], b[1] - a[1]);
Chris@16 564 } else {
Chris@16 565 // Straight line bending around (0, 0)
Chris@16 566 return boost::math::hypot(a[0], a[1]) + boost::math::hypot(b[0], b[1]);
Chris@16 567 }
Chris@16 568 }
Chris@16 569
Chris@16 570 point move_position_toward(point a, double fraction, point b) const
Chris@16 571 {
Chris@16 572 if (segment_within_heart(a, b)) {
Chris@16 573 // Straight line
Chris@16 574 return point(a[0] + (b[0] - a[0]) * fraction,
Chris@16 575 a[1] + (b[1] - a[1]) * fraction);
Chris@16 576 } else {
Chris@16 577 double distance_to_point_a = boost::math::hypot(a[0], a[1]);
Chris@16 578 double distance_to_point_b = boost::math::hypot(b[0], b[1]);
Chris@16 579 double location_of_point = distance_to_point_a /
Chris@16 580 (distance_to_point_a + distance_to_point_b);
Chris@16 581 if (fraction < location_of_point)
Chris@16 582 return point(a[0] * (1 - fraction / location_of_point),
Chris@16 583 a[1] * (1 - fraction / location_of_point));
Chris@16 584 else
Chris@16 585 return point(
Chris@16 586 b[0] * ((fraction - location_of_point) / (1 - location_of_point)),
Chris@16 587 b[1] * ((fraction - location_of_point) / (1 - location_of_point)));
Chris@16 588 }
Chris@16 589 }
Chris@16 590
Chris@16 591 private:
Chris@16 592 shared_ptr<RandomNumberGenerator> gen_ptr;
Chris@16 593 shared_ptr<rand_t> rand;
Chris@16 594 };
Chris@16 595
Chris@16 596 } // namespace boost
Chris@16 597
Chris@16 598 #endif // BOOST_GRAPH_TOPOLOGY_HPP