Subversion Repositories Scribus

Rev

Rev 15347 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
15347 fschmid 1
/*
2
 * d2.h - Lifts one dimensional objects into 2d
12065 fschmid 3
 *
4
 * Copyright 2007 Michael Sloan <mgsloan@gmail.com>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, output to the Free Software
18122 mrdocs 16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
12065 fschmid 17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 */
30
 
31
#ifndef _2GEOM_D2  //If this is change, change the guard in rect.h as well.
32
#define _2GEOM_D2
33
 
34
#include "point.h"
35
#include "interval.h"
15347 fschmid 36
#include "matrix.h"
12065 fschmid 37
 
38
#include <boost/concept_check.hpp>
39
#include "concepts.h"
40
 
41
namespace Geom{
15347 fschmid 42
 
12065 fschmid 43
template <class T>
44
class D2{
45
    //BOOST_CLASS_REQUIRE(T, boost, AssignableConcept);
46
  private:
47
    T f[2];
48
 
49
  public:
50
    D2() {f[X] = f[Y] = T();}
51
    explicit D2(Point const &a) {
52
        f[X] = T(a[X]); f[Y] = T(a[Y]);
53
    }
54
 
55
    D2(T const &a, T const &b) {
56
        f[X] = a;
57
        f[Y] = b;
58
    }
59
 
60
    //TODO: ask mental about operator= as seen in Point
61
 
62
    T& operator[](unsigned i)              { return f[i]; }
63
    T const & operator[](unsigned i) const { return f[i]; }
64
 
65
    //IMPL: FragmentConcept
66
    typedef Point output_type;
67
    bool isZero() const {
68
        boost::function_requires<FragmentConcept<T> >();
69
        return f[X].isZero() && f[Y].isZero();
70
    }
71
    bool isConstant() const {
72
        boost::function_requires<FragmentConcept<T> >();
73
        return f[X].isConstant() && f[Y].isConstant();
74
    }
75
    bool isFinite() const {
76
        boost::function_requires<FragmentConcept<T> >();
77
        return f[X].isFinite() && f[Y].isFinite();
78
    }
79
    Point at0() const {
80
        boost::function_requires<FragmentConcept<T> >();
81
        return Point(f[X].at0(), f[Y].at0());
82
    }
83
    Point at1() const {
84
        boost::function_requires<FragmentConcept<T> >();
85
        return Point(f[X].at1(), f[Y].at1());
86
    }
87
    Point valueAt(double t) const {
88
        boost::function_requires<FragmentConcept<T> >();
89
        return (*this)(t);
90
    }
15347 fschmid 91
    std::vector<Point > valueAndDerivatives(double t, unsigned count) const {
92
        std::vector<Coord> x = f[X].valueAndDerivatives(t, count),
93
                           y = f[Y].valueAndDerivatives(t, count);
94
        std::vector<Point> res;
95
        for(unsigned i = 0; i < count; i++) {
96
            res.push_back(Point(x[i], y[i]));
12065 fschmid 97
        }
98
        return res;
99
    }
100
    D2<SBasis> toSBasis() const {
101
        boost::function_requires<FragmentConcept<T> >();
102
        return D2<SBasis>(f[X].toSBasis(), f[Y].toSBasis());
103
    }
104
 
105
    Point operator()(double t) const;
106
    Point operator()(double x, double y) const;
107
};
108
template <typename T>
109
inline D2<T> reverse(const D2<T> &a) {
110
    boost::function_requires<FragmentConcept<T> >();
111
    return D2<T>(reverse(a[X]), reverse(a[Y]));
112
}
113
 
114
template <typename T>
115
inline D2<T> portion(const D2<T> &a, Coord f, Coord t) {
116
    boost::function_requires<FragmentConcept<T> >();
117
    return D2<T>(portion(a[X], f, t), portion(a[Y], f, t));
118
}
119
 
120
//IMPL: boost::EqualityComparableConcept
121
template <typename T>
122
inline bool
123
operator==(D2<T> const &a, D2<T> const &b) {
124
    boost::function_requires<boost::EqualityComparableConcept<T> >();
125
    return a[0]==b[0] && a[1]==b[1];
126
}
127
template <typename T>
128
inline bool
129
operator!=(D2<T> const &a, D2<T> const &b) {
130
    boost::function_requires<boost::EqualityComparableConcept<T> >();
131
    return a[0]!=b[0] || a[1]!=b[1];
132
}
133
 
134
//IMPL: NearConcept
135
template <typename T>
136
inline bool
137
are_near(D2<T> const &a, D2<T> const &b, double tol) {
138
    boost::function_requires<NearConcept<T> >();
139
    return are_near(a[0], b[0]) && are_near(a[1], b[1]);
140
}
141
 
142
//IMPL: AddableConcept
143
template <typename T>
144
inline D2<T>
145
operator+(D2<T> const &a, D2<T> const &b) {
146
    boost::function_requires<AddableConcept<T> >();
147
 
148
    D2<T> r;
149
    for(unsigned i = 0; i < 2; i++)
150
        r[i] = a[i] + b[i];
151
    return r;
152
}
153
template <typename T>
154
inline D2<T>
155
operator-(D2<T> const &a, D2<T> const &b) {
156
    boost::function_requires<AddableConcept<T> >();
157
 
158
    D2<T> r;
159
    for(unsigned i = 0; i < 2; i++)
160
        r[i] = a[i] - b[i];
161
    return r;
162
}
163
template <typename T>
164
inline D2<T>
165
operator+=(D2<T> &a, D2<T> const &b) {
166
    boost::function_requires<AddableConcept<T> >();
167
 
168
    for(unsigned i = 0; i < 2; i++)
169
        a[i] += b[i];
170
    return a;
171
}
172
template <typename T>
173
inline D2<T>
174
operator-=(D2<T> &a, D2<T> const & b) {
175
    boost::function_requires<AddableConcept<T> >();
176
 
177
    for(unsigned i = 0; i < 2; i++)
178
        a[i] -= b[i];
179
    return a;
180
}
181
 
182
//IMPL: ScalableConcept
183
template <typename T>
184
inline D2<T>
185
operator-(D2<T> const & a) {
186
    boost::function_requires<ScalableConcept<T> >();
187
    D2<T> r;
188
    for(unsigned i = 0; i < 2; i++)
189
        r[i] = -a[i];
190
    return r;
191
}
192
template <typename T>
193
inline D2<T>
194
operator*(D2<T> const & a, Point const & b) {
195
    boost::function_requires<ScalableConcept<T> >();
196
 
197
    D2<T> r;
198
    for(unsigned i = 0; i < 2; i++)
199
        r[i] = a[i] * b[i];
200
    return r;
201
}
202
template <typename T>
203
inline D2<T>
204
operator/(D2<T> const & a, Point const & b) {
205
    boost::function_requires<ScalableConcept<T> >();
206
    //TODO: b==0?
207
    D2<T> r;
208
    for(unsigned i = 0; i < 2; i++)
209
        r[i] = a[i] / b[i];
210
    return r;
211
}
212
template <typename T>
213
inline D2<T>
214
operator*=(D2<T> &a, Point const & b) {
215
    boost::function_requires<ScalableConcept<T> >();
216
 
217
    for(unsigned i = 0; i < 2; i++)
218
        a[i] *= b[i];
219
    return a;
220
}
221
template <typename T>
222
inline D2<T>
223
operator/=(D2<T> &a, Point const & b) {
224
    boost::function_requires<ScalableConcept<T> >();
225
    //TODO: b==0?
226
    for(unsigned i = 0; i < 2; i++)
227
        a[i] /= b[i];
228
    return a;
229
}
230
 
231
template <typename T>
232
inline D2<T> operator*(D2<T> const & a, double b) { return D2<T>(a[0]*b, a[1]*b); }
233
template <typename T>
234
inline D2<T> operator*=(D2<T> & a, double b) { a[0] *= b; a[1] *= b; return a; }
235
template <typename T>
236
inline D2<T> operator/(D2<T> const & a, double b) { return D2<T>(a[0]/b, a[1]/b); }
237
template <typename T>
238
inline D2<T> operator/=(D2<T> & a, double b) { a[0] /= b; a[1] /= b; return a; }
239
 
240
template<typename T>
15347 fschmid 241
D2<T> operator*(D2<T> const &v, Matrix const &m) {
12065 fschmid 242
    boost::function_requires<AddableConcept<T> >();
243
    boost::function_requires<ScalableConcept<T> >();
244
    D2<T> ret;
245
    for(unsigned i = 0; i < 2; i++)
246
        ret[i] = v[X] * m[i] + v[Y] * m[i + 2] + m[i + 4];
247
    return ret;
248
}
249
 
250
//IMPL: OffsetableConcept
251
template <typename T>
252
inline D2<T>
253
operator+(D2<T> const & a, Point b) {
254
    boost::function_requires<OffsetableConcept<T> >();
255
    D2<T> r;
256
    for(unsigned i = 0; i < 2; i++)
257
        r[i] = a[i] + b[i];
258
    return r;
259
}
260
template <typename T>
261
inline D2<T>
262
operator-(D2<T> const & a, Point b) {
263
    boost::function_requires<OffsetableConcept<T> >();
264
    D2<T> r;
265
    for(unsigned i = 0; i < 2; i++)
266
        r[i] = a[i] - b[i];
267
    return r;
268
}
269
template <typename T>
270
inline D2<T>
271
operator+=(D2<T> & a, Point b) {
272
    boost::function_requires<OffsetableConcept<T> >();
273
    for(unsigned i = 0; i < 2; i++)
274
        a[i] += b[i];
275
    return a;
276
}
277
template <typename T>
278
inline D2<T>
279
operator-=(D2<T> & a, Point b) {
280
    boost::function_requires<OffsetableConcept<T> >();
281
    for(unsigned i = 0; i < 2; i++)
282
        a[i] -= b[i];
283
    return a;
284
}
285
 
286
template <typename T>
287
inline T
288
dot(D2<T> const & a, D2<T> const & b) {
289
    boost::function_requires<AddableConcept<T> >();
290
    boost::function_requires<MultiplicableConcept<T> >();
291
 
292
    T r;
293
    for(unsigned i = 0; i < 2; i++)
294
        r += a[i] * b[i];
295
    return r;
296
}
297
 
298
template <typename T>
299
inline T
300
cross(D2<T> const & a, D2<T> const & b) {
301
    boost::function_requires<ScalableConcept<T> >();
302
    boost::function_requires<MultiplicableConcept<T> >();
303
 
304
    return a[1] * b[0] - a[0] * b[1];
305
}
306
 
307
 
308
//equivalent to cw/ccw, for use in situations where rotation direction doesn't matter.
309
template <typename T>
310
inline D2<T>
311
rot90(D2<T> const & a) {
312
    boost::function_requires<ScalableConcept<T> >();
313
    return D2<T>(-a[Y], a[X]);
314
}
315
 
316
//TODO: concepterize the following functions
317
template <typename T>
318
inline D2<T>
319
compose(D2<T> const & a, T const & b) {
320
    D2<T> r;
321
    for(unsigned i = 0; i < 2; i++)
322
        r[i] = compose(a[i],b);
323
    return r;
324
}
325
 
326
template <typename T>
327
inline D2<T>
328
compose_each(D2<T> const & a, D2<T> const & b) {
329
    D2<T> r;
330
    for(unsigned i = 0; i < 2; i++)
331
        r[i] = compose(a[i],b[i]);
332
    return r;
333
}
334
 
335
template <typename T>
336
inline D2<T>
337
compose_each(T const & a, D2<T> const & b) {
338
    D2<T> r;
339
    for(unsigned i = 0; i < 2; i++)
340
        r[i] = compose(a,b[i]);
341
    return r;
342
}
343
 
344
 
345
template<typename T>
346
inline Point
347
D2<T>::operator()(double t) const {
348
    Point p;
349
    for(unsigned i = 0; i < 2; i++)
350
       p[i] = (*this)[i](t);
351
    return p;
352
}
353
 
354
//TODO: we might want to have this take a Point as the parameter.
355
template<typename T>
356
inline Point
357
D2<T>::operator()(double x, double y) const {
358
    Point p;
359
    for(unsigned i = 0; i < 2; i++)
360
       p[i] = (*this)[i](x, y);
361
    return p;
362
}
363
 
364
 
365
template<typename T>
366
D2<T> derivative(D2<T> const & a) {
367
    return D2<T>(derivative(a[X]), derivative(a[Y]));
368
}
369
template<typename T>
370
D2<T> integral(D2<T> const & a) {
371
    return D2<T>(integral(a[X]), integral(a[Y]));
372
}
373
 
374
} //end namespace Geom
375
 
376
#include "rect.h"
377
#include "d2-sbasis.h"
378
 
379
namespace Geom{
380
 
381
//Some D2 Fragment implementation which requires rect:
382
template <typename T>
15347 fschmid 383
Rect bounds_fast(const D2<T> &a) {
384
    boost::function_requires<FragmentConcept<T> >();        
385
    return Rect(bounds_fast(a[X]), bounds_fast(a[Y]));
12065 fschmid 386
}
387
template <typename T>
15347 fschmid 388
Rect bounds_exact(const D2<T> &a) {
389
    boost::function_requires<FragmentConcept<T> >();        
390
    return Rect(bounds_exact(a[X]), bounds_exact(a[Y]));
12065 fschmid 391
}
392
template <typename T>
15347 fschmid 393
Rect bounds_local(const D2<T> &a, const Interval &t) {
394
    boost::function_requires<FragmentConcept<T> >();        
395
    return Rect(bounds_local(a[X], t), bounds_local(a[Y], t));
12065 fschmid 396
}
397
};
398
 
399
/*
400
  Local Variables:
401
  mode:c++
402
  c-file-style:"stroustrup"
403
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
404
  indent-tabs-mode:nil
405
  fill-column:99
406
  End:
407
*/
408
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
409
#endif