Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
angle-test.cpp
Go to the documentation of this file.
1/*
5 * Authors:
6 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
7 *
8 * Copyright 2015 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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#include <2geom/angle.h>
35#include <glib.h>
36#include "testing.h"
37
38using namespace Geom;
39
40TEST(AngleIntervalTest, InnerAngleConstrutor) {
41 std::vector<AngleInterval> ivs;
42
43 ivs.emplace_back(0, M_PI, true);
44 ivs.emplace_back(0, M_PI, false);
45 ivs.emplace_back(M_PI, 0, true);
46 ivs.emplace_back(M_PI, 0, false);
47 ivs.emplace_back(Angle(0), Angle(0), Angle(M_PI));
48
49 for (auto & iv : ivs) {
50 AngleInterval inner(iv.angleAt(0), iv.angleAt(0.5), iv.angleAt(1));
51 EXPECT_EQ(inner, iv);
52 }
53}
54
55TEST(AngleIntervalTest, Containment) {
56 AngleInterval a(0, M_PI, true);
57 AngleInterval b(0, M_PI, false);
58 AngleInterval c(M_PI, 0, true);
59 AngleInterval d(M_PI, 0, false);
61
62 EXPECT_TRUE(a.contains(1.));
63 EXPECT_FALSE(a.contains(5.));
64 EXPECT_EQ(a.extent(), M_PI);
65
66 EXPECT_FALSE(b.contains(1.));
67 EXPECT_TRUE(b.contains(5.));
68 EXPECT_EQ(b.extent(), M_PI);
69
70 EXPECT_FALSE(c.contains(1.));
71 EXPECT_TRUE(c.contains(5.));
72 EXPECT_EQ(c.extent(), M_PI);
73
74 EXPECT_TRUE(d.contains(1.));
75 EXPECT_FALSE(d.contains(5.));
76 EXPECT_EQ(d.extent(), M_PI);
77
78 EXPECT_TRUE(e.contains(1.));
79 EXPECT_TRUE(e.contains(5.));
80 EXPECT_EQ(e.extent(), 2*M_PI);
81}
82
83TEST(AngleIntervalTest, TimeAtAngle) {
84 Coord pi32 = (3./2.)*M_PI;
85 AngleInterval a(M_PI, pi32, true);
86 AngleInterval b(pi32, M_PI, true);
87 AngleInterval c(M_PI, 0, false);
88 AngleInterval d(M_PI/2, M_PI, false);
91 Interval unit(0, 1);
92
93 EXPECT_EQ(a.timeAtAngle(M_PI), 0);
94 EXPECT_EQ(a.timeAtAngle(pi32), 1);
95 EXPECT_EQ(a.extent(), M_PI/2);
96 for (Coord t = -1; t <= 2; t += 0.125) {
97 Coord angle = Geom::lerp(t, M_PI, pi32);
98 Coord ti = a.timeAtAngle(angle);
99 EXPECT_EQ(unit.contains(ti), a.contains(angle));
100 EXPECT_FLOAT_EQ(ti, t);
101 }
102
103 EXPECT_EQ(b.timeAtAngle(pi32), 0);
104 EXPECT_EQ(b.timeAtAngle(M_PI), 1);
105 EXPECT_EQ(b.extent(), pi32);
106 EXPECT_FLOAT_EQ(b.timeAtAngle(M_PI/4), 0.5);
107 EXPECT_FLOAT_EQ(b.timeAtAngle(0), 1./3.);
108 EXPECT_FLOAT_EQ(b.timeAtAngle((11./8)*M_PI), -1./12);
109 for (Coord t = -0.125; t <= 1.125; t += 0.0625) {
110 Coord angle = Geom::lerp(t, pi32, 3*M_PI);
111 Coord ti = b.timeAtAngle(angle);
112 EXPECT_EQ(unit.contains(ti), b.contains(angle));
113 EXPECT_FLOAT_EQ(ti, t);
114 }
115
116 EXPECT_EQ(c.timeAtAngle(M_PI), 0);
117 EXPECT_EQ(c.timeAtAngle(0), 1);
118 EXPECT_EQ(c.extent(), M_PI);
119 EXPECT_FLOAT_EQ(c.timeAtAngle(M_PI/2), 0.5);
120 for (Coord t = -0.25; t <= 1.25; t += 0.125) {
121 Coord angle = Geom::lerp(t, M_PI, 0);
122 Coord ti = c.timeAtAngle(angle);
123 EXPECT_EQ(unit.contains(ti), c.contains(angle));
124 EXPECT_FLOAT_EQ(ti, t);
125 }
126
127 EXPECT_EQ(d.timeAtAngle(M_PI/2), 0);
128 EXPECT_EQ(d.timeAtAngle(M_PI), 1);
129 EXPECT_EQ(d.extent(), pi32);
130 EXPECT_FLOAT_EQ(d.timeAtAngle(-M_PI/4), 0.5);
131 for (Coord t = -0.125; t <= 1.125; t += 0.0625) {
132 Coord angle = Geom::lerp(t, M_PI/2, -M_PI);
133 Coord ti = d.timeAtAngle(angle);
134 EXPECT_EQ(unit.contains(ti), d.contains(angle));
135 EXPECT_FLOAT_EQ(ti, t);
136 }
137
138 EXPECT_EQ(e.timeAtAngle(M_PI), 0);
139 EXPECT_EQ(e.extent(), 2*M_PI);
140 EXPECT_FLOAT_EQ(e.timeAtAngle(0), 0.5);
141 for (Coord t = 0; t < 1; t += 0.125) {
142 Coord angle = Geom::lerp(t, M_PI, 3*M_PI);
143 Coord ti = e.timeAtAngle(angle);
144 EXPECT_EQ(unit.contains(ti), true);
145 EXPECT_EQ(e.contains(angle), true);
146 EXPECT_FLOAT_EQ(ti, t);
147 }
148
149 EXPECT_EQ(f.timeAtAngle(M_PI), 0);
150 EXPECT_EQ(f.extent(), 2*M_PI);
151 EXPECT_FLOAT_EQ(e.timeAtAngle(0), 0.5);
152 for (Coord t = 0; t < 1; t += 0.125) {
153 Coord angle = Geom::lerp(t, M_PI, -M_PI);
154 Coord ti = f.timeAtAngle(angle);
155 EXPECT_EQ(unit.contains(ti), true);
156 EXPECT_EQ(f.contains(angle), true);
157 EXPECT_FLOAT_EQ(ti, t);
158 }
159}
160
161TEST(AngleIntervalTest, AngleAt) {
162 Coord pi32 = (3./2.)*M_PI;
163 AngleInterval a(M_PI, pi32, true);
164 AngleInterval c(M_PI, 0, false);
167
168 EXPECT_EQ(a.angleAt(0), M_PI);
169 EXPECT_EQ(a.angleAt(1), pi32);
170 EXPECT_EQ(a.extent(), M_PI/2);
171 for (Coord t = -1; t <= 2; t += 0.125) {
172 EXPECT_FLOAT_EQ(a.angleAt(t), Angle(Geom::lerp(t, M_PI, pi32)));
173 }
174
175 EXPECT_EQ(c.angleAt(0), M_PI);
176 EXPECT_EQ(c.angleAt(1), 0.);
177 EXPECT_EQ(c.extent(), M_PI);
178 for (Coord t = -0.25; t <= 1.25; t += 0.0625) {
179 EXPECT_FLOAT_EQ(c.angleAt(t), Angle(Geom::lerp(t, M_PI, 0)));
180 }
181
182 EXPECT_EQ(f1.angleAt(0), 0.);
183 EXPECT_EQ(f1.angleAt(1), 0.);
184 for (Coord t = 0; t < 1; t += 0.125) {
185 EXPECT_FLOAT_EQ(f1.angleAt(t), Angle(Geom::lerp(t, 0, 2*M_PI)));
186 }
187 EXPECT_EQ(f2.angleAt(0), M_PI);
188 EXPECT_EQ(f2.angleAt(1), M_PI);
189 for (Coord t = 0; t < 1; t += 0.125) {
190 EXPECT_FLOAT_EQ(f2.angleAt(t), Angle(Geom::lerp(t, M_PI, -M_PI)));
191 }
192}
193
194TEST(AngleIntervalTest, Extent) {
195 Coord pi32 = (3./2.)*M_PI;
196 AngleInterval a(M_PI, pi32, true);
197 AngleInterval b(pi32, M_PI, true);
198 AngleInterval c(M_PI, 0, false);
199 AngleInterval d(M_PI/2, M_PI, false);
200
201 EXPECT_EQ(a.extent(), M_PI/2);
202 EXPECT_EQ(a.sweepAngle(), M_PI/2);
203 EXPECT_EQ(b.extent(), pi32);
204 EXPECT_EQ(b.sweepAngle(), pi32);
205 EXPECT_EQ(c.extent(), M_PI);
206 EXPECT_EQ(c.sweepAngle(), -M_PI);
207 EXPECT_EQ(d.extent(), pi32);
208 EXPECT_EQ(d.sweepAngle(), -pi32);
209}
210
211TEST(DegRadConversion, PreservesPI180)
212{
213 EXPECT_EQ(deg_from_rad(M_PI), 180);
214 EXPECT_EQ(rad_from_deg(180), M_PI);
215}
Various trigoniometric helper functions.
Directed angular interval.
Definition angle.h:188
Coord sweepAngle() const
Get the sweep angle of the interval.
Definition angle.h:352
Angle angleAt(Coord t) const
Get an angle corresponding to the specified time value.
Definition angle.h:288
Coord timeAtAngle(Angle a) const
Compute a time value that would evaluate to the given angle.
Definition angle.h:299
Coord extent() const
Extent of the angle interval.
Definition angle.h:342
static AngleInterval create_full(Angle start, bool sweep=true)
Definition angle.h:369
bool contains(Angle a) const
Check whether the interval includes the given angle.
Definition angle.h:326
Wrapper for angular values.
Definition angle.h:73
constexpr bool contains(C val) const
Check whether the interval includes this number.
Range of real numbers that is never empty.
Definition interval.h:59
double inner(valarray< double > const &x, valarray< double > const &y)
double c[8][4]
constexpr Coord lerp(Coord t, Coord a, Coord b)
Numerically stable linear interpolation.
Definition coord.h:97
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
Various utility functions.
Definition affine.h:22
TEST(AffineTest, Equality)