Adaptagrams
ortho.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libdialect - A library for computing DiAlEcT layouts:
5  * D = Decompose/Distribute
6  * A = Arrange
7  * E = Expand/Emend
8  * T = Transform
9  *
10  * Copyright (C) 2018 Monash University
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * See the file LICENSE.LGPL distributed with the library.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21  *
22  * Author(s): Steve Kieffer <http://skieffer.info>
23 */
24 
25 #ifndef DIALECT_ORTHO_H
26 #define DIALECT_ORTHO_H
27 
28 #include <vector>
29 #include <set>
30 #include <memory>
31 #include <map>
32 #include <string>
33 #include <functional>
34 #include <algorithm>
35 #include <utility>
36 
37 #include "libvpsc/rectangle.h"
38 #include "libavoid/libavoid.h"
39 
40 #include "libdialect/commontypes.h"
41 
42 namespace dialect {
43 
44 class Node;
45 
46 enum class CompassDir {
47  EAST,
48  SOUTH,
49  WEST,
50  NORTH,
51  SE,
52  SW,
53  NW,
54  NE
55 };
56 
57 enum class CardinalDir {
58  EAST,
59  SOUTH,
60  WEST,
61  NORTH
62 };
63 
64 typedef std::vector<CompassDir> CompassDirs;
65 typedef std::vector<CardinalDir> CardinalDirs;
66 
67 struct Compass {
68 
70  static bool isVertical(CompassDir d) {
71  return d == CompassDir::NORTH || d == CompassDir::SOUTH;
72  }
73 
75  static bool isHorizontal(CompassDir d) {
76  return d == CompassDir::EAST || d == CompassDir::WEST;
77  }
78 
80  static bool isVerticalCard(CardinalDir d) {
81  return d == CardinalDir::NORTH || d == CardinalDir::SOUTH;
82  }
83 
85  static bool isHorizontalCard(CardinalDir d) {
86  return d == CardinalDir::EAST || d == CardinalDir::WEST;
87  }
88 
90  static bool isInDim(CompassDir d, vpsc::Dim dim) {
91  return dim == vpsc::HORIZONTAL ? isHorizontal(d) : isVertical(d);
92  }
93 
96  static bool isIncreasing(CompassDir d) {
97  return d == CompassDir::EAST || d == CompassDir::SOUTH;
98  }
99 
102  static bool isDecreasing(CompassDir d) {
103  return d == CompassDir::NORTH || d == CompassDir::WEST;
104  }
105 
108  static bool isIncreasingCard(CardinalDir d) {
109  return d == CardinalDir::EAST || d == CardinalDir::SOUTH;
110  }
111 
114  static bool isDecreasingCard(CardinalDir d) {
115  return d == CardinalDir::WEST || d == CardinalDir::NORTH;
116  }
117 
120  static bool sameDimension(CardinalDir d0, CardinalDir d1) {
121  return (unsigned)(d0) % 2 == (unsigned)(d1) % 2;
122  }
123 
126  static bool arePerpendicular(CardinalDir d0, CardinalDir d1) {
127  return (unsigned)(d0) % 2 != (unsigned)(d1) % 2;
128  }
129 
132  static CompassDir compassDirection(Avoid::Point p0, Avoid::Point p1);
133 
136  static CompassDir compassDirection(std::shared_ptr<Node> u0, std::shared_ptr<Node> u1);
137 
140  static CardinalDir cardinalDirection(Avoid::Point p0, Avoid::Point p1);
141 
144  static CardinalDir cardinalDirection(std::shared_ptr<Node> u0, std::shared_ptr<Node> u1);
145 
147  static bool isCardinal(CompassDir d) { return ((unsigned) d) < 4; }
148 
150  static CardinalDir cardRotateCw90(CardinalDir d);
151 
153  static CardinalDir cardRotateAcw90(CardinalDir d);
154 
156  static CardinalDir cardFlip(CardinalDir d);
157 
159  static std::string dirToString(CompassDir d);
160 
162  static std::string cardToString(CardinalDir d);
163 
165  static CardinalDirs cardinalComponents(CompassDir d);
166 
173  static PlaneMap getRotationFunction(CardinalDir fromDir, CardinalDir toDir);
174 
181  static InplacePlaneMap getInplaceRotationFunction(CardinalDir fromDir, CardinalDir toDir);
182 
189  static Avoid::Point vectorSigns(CompassDir d);
190 
192  static const CardinalDirs cwCards;
193 
195  static const CardinalDirs acwCards;
196 
200  static const CompassDirs cwAllDoubled;
201 
203  static const CompassDirs acwAllDoubled;
204 
206  static const std::set<CardinalDir> vertical;
207 
209  static const std::set<CardinalDir> horizontal;
210 
212  static const std::map<CardinalDir, Avoid::ConnDirFlag> libavoidConnDirs;
213 
215  static const std::map<CompassDir, CompassDir> rotateCw90;
216 
218  static const std::map<CompassDir, CompassDir> flip;
219 
221  static const std::map<CardinalDir, vpsc::Dim> varDim;
222 
224  static const std::map<CardinalDir, vpsc::Dim> constDim;
225 
226 };
227 
228 typedef std::pair<double, double> interval;
229 
230 struct LineSegment {
231  LineSegment(Avoid::Point p0, Avoid::Point p1)
232  : p0(p0), p1(p1),
233  x0(p0.x), y0(p0.y),
234  x1(p1.x), y1(p1.y),
235  direc(Compass::cardinalDirection(p0, p1)),
236  varDim(Compass::varDim.at(direc)),
237  constDim(Compass::constDim.at(direc))
238  {
239  if (Compass::isVerticalCard(direc)) {
240  z = x0; w0 = y0; w1 = y1;
241  } else {
242  z = y0; w0 = x0; w1 = x1;
243  }
244  auto p = std::minmax(w0, w1);
245  wl = p.first;
246  wh = p.second;
247  length = wh - wl;
248  }
249 
251  double getConstCoord(void) const { return z; }
252 
257  bool closedIntervalIntersects(double a, double b) const;
258 
263  bool openIntervalIntersects(double a, double b) const;
264 
268  bool closedIntervalIncludesCoord(double a) const;
269 
273  bool openIntervalIncludesCoord(double a) const;
274 
283  interval closedIntervalIntersection(double a, double b) const;
284 
293  interval openIntervalIntersection(double a, double b) const;
294 
300  int ptOnWhichSide(Avoid::Point p) const;
301 
307  int coordOnWhichSide(double z1) const;
308 
309  static const double EPSILON;
310 
311  Avoid::Point p0;
312  Avoid::Point p1;
314  double x0;
315  double y0;
317  double x1;
318  double y1;
320  CardinalDir direc;
322  vpsc::Dim varDim;
324  vpsc::Dim constDim;
326  double z;
328  double w0;
330  double w1;
332  double wl;
334  double wh;
336  double length;
337 };
338 
339 
340 } // namespace dialect
341 
342 #endif // DIALECT_ORTHO_H
Standard libavoid include file which includes all libavoid header files.
libdialect: A library for computing human-like orthogonal network (DiAlEcT) layouts.
Definition: cola.h:44
Cardinal constraints imply both a separation and an alignment:
The Point class defines a point in the plane.
Definition: geomtypes.h:52
The x-dimension (0).
Definition: rectangle.h:43
Dim
Indicates the x- or y-dimension.
Definition: rectangle.h:41