1 /*
2  *  linear.h - Linear fragment function class
3  *
4  *  Authors:
5  *   Nathan Hurst <njh@mail.csse.monash.edu.au>
6  *   Michael Sloan <mgsloan@gmail.com>
7  *
8  * Copyright (C) 2006-2007 authors
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it either under the terms of the GNU Lesser General Public
12  * License version 2.1 as published by the Free Software Foundation
13  * (the "LGPL") or, at your option, under the terms of the Mozilla
14  * Public License Version 1.1 (the "MPL"). If you do not alter this
15  * notice, a recipient may use your version of this file under either
16  * the MPL or the LGPL.
17  *
18  * You should have received a copy of the LGPL along with this library
19  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  * You should have received a copy of the MPL along with this library
22  * in the file COPYING-MPL-1.1
23  *
24  * The contents of this file are subject to the Mozilla Public License
25  * Version 1.1 (the "License"); you may not use this file except in
26  * compliance with the License. You may obtain a copy of the License at
27  * http://www.mozilla.org/MPL/
28  *
29  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
30  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
31  * the specific language governing rights and limitations.
32  */
33 
34 #ifndef SEEN_LINEAR_H
35 #define SEEN_LINEAR_H
36 #include "isnan.h"
37 #include "interval.h"
38 
39 namespace Geom{
40 
lerp(double t,double a,double b)41 inline double lerp(double t, double a, double b) { return a*(1-t) + b*t; }
42 
43 class SBasis;
44 
45 class Hat{
46 public:
Hat()47     Hat () {}
Hat(double d)48     Hat(double d) :d(d) {}
49     operator double() const { return d; }
50     double d;
51 };
52 
53 class Tri{
54 public:
Tri()55     Tri () {}
Tri(double d)56     Tri(double d) :d(d) {}
57     operator double() const { return d; }
58     double d;
59 };
60 
61 class Linear{
62 public:
63     double a[2];
Linear()64     Linear() {}
Linear(double aa,double b)65     Linear(double aa, double b) {a[0] = aa; a[1] = b;}
Linear(Hat h,Tri t)66     Linear(Hat h, Tri t) {
67         a[0] = double(h) - double(t)/2;
68         a[1] = double(h) + double(t)/2;
69     }
70 
Linear(Hat h)71     Linear(Hat h) {
72         a[0] = double(h);
73         a[1] = double(h);
74     }
75 
76     double operator[](const int i) const {
77         assert(i >= 0);
78         assert(i < 2);
79         return a[i];
80     }
81     double& operator[](const int i) {
82         assert(i >= 0);
83         assert(i < 2);
84         return a[i];
85     }
86 
87     //IMPL: FragmentConcept
88     typedef double output_type;
isZero()89     inline bool isZero() const { return a[0] == 0 && a[1] == 0; }
isConstant()90     inline bool isConstant() const { return a[0] == a[1]; }
isFinite()91     inline bool isFinite() const { return is_finite(a[0]) && is_finite(a[1]); }
92 
at0()93     inline double at0() const { return a[0]; }
at1()94     inline double at1() const { return a[1]; }
95 
valueAt(double t)96     inline double valueAt(double t) const { return lerp(t, a[0], a[1]); }
operator()97     inline double operator()(double t) const { return valueAt(t); }
98 
99     //defined in sbasis.h
100     inline SBasis toSBasis() const;
101 
bounds_exact()102     inline Interval bounds_exact() const { return Interval(a[0], a[1]); }
bounds_fast()103     inline Interval bounds_fast() const { return bounds_exact(); }
bounds_local(double u,double v)104     inline Interval bounds_local(double u, double v) const { return Interval(valueAt(u), valueAt(v)); }
105 
Tri()106     operator Tri() const {
107         return a[1] - a[0];
108     }
Hat()109     operator Hat() const {
110         return (a[1] + a[0])/2;
111     }
112 };
113 
reverse(Linear const & a)114 inline Linear reverse(Linear const &a) { return Linear(a[1], a[0]); }
115 
116 //IMPL: AddableConcept
117 inline Linear operator+(Linear const & a, Linear const & b) {
118     return Linear(a[0] + b[0], a[1] + b[1]);
119 }
120 inline Linear operator-(Linear const & a, Linear const & b) {
121     return Linear(a[0] - b[0], a[1] - b[1]);
122 }
123 inline Linear& operator+=(Linear & a, Linear const & b) {
124     a[0] += b[0]; a[1] += b[1];
125     return a;
126 }
127 inline Linear& operator-=(Linear & a, Linear const & b) {
128     a[0] -= b[0]; a[1] -= b[1];
129     return a;
130 }
131 //IMPL: OffsetableConcept
132 inline Linear operator+(Linear const & a, double b) {
133     return Linear(a[0] + b, a[1] + b);
134 }
135 inline Linear operator-(Linear const & a, double b) {
136     return Linear(a[0] - b, a[1] - b);
137 }
138 inline Linear& operator+=(Linear & a, double b) {
139     a[0] += b; a[1] += b;
140     return a;
141 }
142 inline Linear& operator-=(Linear & a, double b) {
143     a[0] -= b; a[1] -= b;
144     return a;
145 }
146 //IMPL: boost::EqualityComparableConcept
147 inline bool operator==(Linear const & a, Linear const & b) {
148     return a[0] == b[0] && a[1] == b[1];
149 }
150 inline bool operator!=(Linear const & a, Linear const & b) {
151     return a[0] != b[0] || a[1] != b[1];
152 }
153 //IMPL: ScalableConcept
154 inline Linear operator-(Linear const &a) {
155     return Linear(-a[0], -a[1]);
156 }
157 inline Linear operator*(Linear const & a, double b) {
158     return Linear(a[0]*b, a[1]*b);
159 }
160 inline Linear operator/(Linear const & a, double b) {
161     return Linear(a[0]/b, a[1]/b);
162 }
163 inline Linear operator*=(Linear & a, double b) {
164     a[0] *= b; a[1] *= b;
165     return a;
166 }
167 inline Linear operator/=(Linear & a, double b) {
168     a[0] /= b; a[1] /= b;
169     return a;
170 }
171 };
172 
173 #endif //SEEN_LINEAR_H
174