25 #ifndef DIALECT_UTIL_H 26 #define DIALECT_UTIL_H 49 return a==b || std::abs(a-b) < std::abs(std::min(a,b))*std::numeric_limits<double>::epsilon()*error_factor;
55 return a==b || std::abs(a-b) < tol;
61 template<
typename ... Args>
64 size_t size = std::snprintf(
nullptr, 0, format.c_str(), args ... ) + 1;
65 std::unique_ptr<char[]> buf(
new char[ size ] );
66 std::snprintf( buf.get(), size, format.c_str(), args ... );
67 return std::string( buf.get(), buf.get() + size - 1 );
76 Matrix2d(
int rows,
int cols) : rows(rows), cols(cols), data(rows*cols)
79 T operator()(
int i,
int j)
const 83 return data[i*cols+j];
85 T& operator()(
int i,
int j)
89 return data[i*cols+j];
92 std::string toString()
const {
96 for (
int j=0; j<cols; j++) {
97 sprintf(buffer,
" %2d",j);
98 s += std::string(buffer);
100 for (
int i=0; i<rows; i++) {
102 sprintf(buffer,
"%2d",i);
103 s += std::string(buffer);
104 for (
int j=0; j<cols; j++) {
105 sprintf(buffer,
" %2d",data[i*cols+j]);
106 s += std::string(buffer);
128 template <
typename T>
144 int x0 = (int) std::round(x),
145 y0 = (int) std::round(y);
160 int u0 = (int) std::round(x - m_thresh),
161 u1 = (int) std::round(x + m_thresh),
162 v0 = (int) std::round(y - m_thresh),
163 v1 = (int) std::round(y + m_thresh);
165 for (
int u = u0; u <= u1; ++u) {
166 for (
int v = v0; v <= v1; ++v) {
167 for (
auto pair : m_objects[u][v]) {
169 if (fabs(x - p.
x) < m_thresh && fabs(y - p.
y) < m_thresh)
return pair.second;
186 std::map<int, std::map<int, std::vector<std::pair<Avoid::Point, T>>>> m_objects;
199 template <
typename T>
200 std::vector<std::vector<T>>
partition(std::vector<T> items, std::function<
double(T)> key,
double tolerance=0) {
202 std::vector<std::vector<T>> parts;
204 if (items.size() == 0)
return parts;
206 std::sort(items.begin(), items.end(),
207 [&key](
const T &a,
const T &b) ->
bool {
208 return key(a) < key(b);
212 auto it = items.cbegin();
214 std::vector<T> part{firstItem};
216 double avg = key(firstItem);
220 for (
auto jt = ++it; jt != items.cend(); ++jt) {
222 double k = key(item);
226 if (fabs(dk) <= tolerance) {
229 part.push_back(item);
231 avg = (n*avg + k)/(n+1);
236 parts.push_back(part);
244 parts.push_back(part);
250 #endif // DIALECT_UTIL_H double y
The y position.
Definition: geomtypes.h:109
std::vector< std::vector< T > > partition(std::vector< T > items, std::function< double(T)> key, double tolerance=0)
Partition a vector of items according to a key value.
Definition: util.h:200
libdialect: A library for computing human-like orthogonal network (DiAlEcT) layouts.
Definition: cola.h:44
void addObject(double x, double y, T obj)
Add a new object, and say what its x,y-coords are.
Definition: util.h:142
double x
The x position.
Definition: geomtypes.h:107
Dense 2d array, with integer indices.
Definition: util.h:72
std::string string_format(const std::string &format, Args ... args)
String formatting.
Definition: util.h:62
bool approx_equal(double a, double b, double tol=0.000001)
Tolerant equality test for doubles. Uses arbitrary tolerance.
Definition: util.h:53
Contains the interface for various geometry types and classes.
NearbyObjectFinder(double threshold)
Construct a NearbyObjectFinder that looks for objects within a given threshold.
Definition: util.h:135
The Point class defines a point in the plane.
Definition: geomtypes.h:52
T findObject(double x, double y)
Check to see if any object has been stored yet in the open neighbourhood centred at the given coordin...
Definition: util.h:157
bool logically_equal(double a, double b, double error_factor=1.0)
Tolerant equality test for doubles. Generates principled value for tolerance.
Definition: util.h:47