Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(466)

Side by Side Diff: ui/gfx/transform_unittest.cc

Issue 11418040: gfx::Transform API clean-up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/transform.cc ('k') | ui/gfx/transform_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "ui/gfx/transform.h" 8 #include "ui/gfx/transform.h"
9 9
10 #include <cmath> 10 #include <cmath>
11 #include <ostream> 11 #include <ostream>
12 #include <limits> 12 #include <limits>
13 13
14 #include "base/basictypes.h" 14 #include "base/basictypes.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gfx/point.h" 16 #include "ui/gfx/point.h"
17 #include "ui/gfx/point3_f.h" 17 #include "ui/gfx/point3_f.h"
18 #include "ui/gfx/transform_util.h" 18 #include "ui/gfx/transform_util.h"
19 #include "ui/gfx/vector3d_f.h"
19 20
20 namespace gfx { 21 namespace gfx {
21 22
22 namespace { 23 namespace {
23 24
24 bool PointsAreNearlyEqual(const Point3F& lhs, 25 bool PointsAreNearlyEqual(const Point3F& lhs,
25 const Point3F& rhs) { 26 const Point3F& rhs) {
26 float epsilon = 0.0001f; 27 float epsilon = 0.0001f;
27 return lhs.SquaredDistanceTo(rhs) < epsilon; 28 return lhs.SquaredDistanceTo(rhs) < epsilon;
28 } 29 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 110 }
110 if (i == 100) { 111 if (i == 100) {
111 EXPECT_TRUE(rhs == interpolated); 112 EXPECT_TRUE(rhs == interpolated);
112 } else { 113 } else {
113 EXPECT_TRUE(rhs != interpolated); 114 EXPECT_TRUE(rhs != interpolated);
114 } 115 }
115 } 116 }
116 lhs = Transform(); 117 lhs = Transform();
117 rhs = Transform(); 118 rhs = Transform();
118 for (int i = 1; i < 100; ++i) { 119 for (int i = 1; i < 100; ++i) {
119 lhs.SetTranslate(i, i); 120 lhs.MakeIdentity();
120 rhs.SetTranslate(-i, -i); 121 rhs.MakeIdentity();
122 lhs.Translate(i, i);
123 rhs.Translate(-i, -i);
121 EXPECT_TRUE(lhs != rhs); 124 EXPECT_TRUE(lhs != rhs);
122 rhs.ConcatTranslate(2*i, 2*i); 125 rhs.Translate(2*i, 2*i);
123 EXPECT_TRUE(lhs == rhs); 126 EXPECT_TRUE(lhs == rhs);
124 } 127 }
125 } 128 }
126 129
127 TEST(XFormTest, ConcatTranslate) { 130 TEST(XFormTest, ConcatTranslate) {
128 static const struct TestCase { 131 static const struct TestCase {
129 int x1; 132 int x1;
130 int y1; 133 int y1;
131 float tx; 134 float tx;
132 float ty; 135 float ty;
133 int x2; 136 int x2;
134 int y2; 137 int y2;
135 } test_cases[] = { 138 } test_cases[] = {
136 { 0, 0, 10.0f, 20.0f, 10, 20 }, 139 { 0, 0, 10.0f, 20.0f, 10, 20 },
137 { 0, 0, -10.0f, -20.0f, 0, 0 }, 140 { 0, 0, -10.0f, -20.0f, 0, 0 },
138 { 0, 0, -10.0f, -20.0f, -10, -20 }, 141 { 0, 0, -10.0f, -20.0f, -10, -20 },
139 { 0, 0, 142 { 0, 0,
140 std::numeric_limits<float>::quiet_NaN(), 143 std::numeric_limits<float>::quiet_NaN(),
141 std::numeric_limits<float>::quiet_NaN(), 144 std::numeric_limits<float>::quiet_NaN(),
142 10, 20 }, 145 10, 20 },
143 }; 146 };
144 147
145 Transform xform; 148 Transform xform;
146 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 149 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
147 const TestCase& value = test_cases[i]; 150 const TestCase& value = test_cases[i];
148 xform.ConcatTranslate(value.tx, value.ty); 151 Transform translation;
152 translation.Translate(value.tx, value.ty);
153 xform = translation * xform;
149 Point3F p1(value.x1, value.y1, 0); 154 Point3F p1(value.x1, value.y1, 0);
150 Point3F p2(value.x2, value.y2, 0); 155 Point3F p2(value.x2, value.y2, 0);
151 xform.TransformPoint(p1); 156 xform.TransformPoint(p1);
152 if (value.tx == value.tx && 157 if (value.tx == value.tx &&
153 value.ty == value.ty) { 158 value.ty == value.ty) {
154 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 159 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
155 } 160 }
156 } 161 }
157 } 162 }
158 163
159 TEST(XFormTest, ConcatScale) { 164 TEST(XFormTest, ConcatScale) {
160 static const struct TestCase { 165 static const struct TestCase {
161 int before; 166 int before;
162 float scale; 167 float scale;
163 int after; 168 int after;
164 } test_cases[] = { 169 } test_cases[] = {
165 { 1, 10.0f, 10 }, 170 { 1, 10.0f, 10 },
166 { 1, .1f, 1 }, 171 { 1, .1f, 1 },
167 { 1, 100.0f, 100 }, 172 { 1, 100.0f, 100 },
168 { 1, -1.0f, -100 }, 173 { 1, -1.0f, -100 },
169 { 1, std::numeric_limits<float>::quiet_NaN(), 1 } 174 { 1, std::numeric_limits<float>::quiet_NaN(), 1 }
170 }; 175 };
171 176
172 Transform xform; 177 Transform xform;
173 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 178 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
174 const TestCase& value = test_cases[i]; 179 const TestCase& value = test_cases[i];
175 xform.ConcatScale(value.scale, value.scale); 180 Transform scale;
181 scale.Scale(value.scale, value.scale);
182 xform = scale * xform;
176 Point3F p1(value.before, value.before, 0); 183 Point3F p1(value.before, value.before, 0);
177 Point3F p2(value.after, value.after, 0); 184 Point3F p2(value.after, value.after, 0);
178 xform.TransformPoint(p1); 185 xform.TransformPoint(p1);
179 if (value.scale == value.scale) { 186 if (value.scale == value.scale) {
180 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 187 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
181 } 188 }
182 } 189 }
183 } 190 }
184 191
185 TEST(XFormTest, ConcatRotate) { 192 TEST(XFormTest, ConcatRotate) {
186 static const struct TestCase { 193 static const struct TestCase {
187 int x1; 194 int x1;
188 int y1; 195 int y1;
189 float degrees; 196 float degrees;
190 int x2; 197 int x2;
191 int y2; 198 int y2;
192 } test_cases[] = { 199 } test_cases[] = {
193 { 1, 0, 90.0f, 0, 1 }, 200 { 1, 0, 90.0f, 0, 1 },
194 { 1, 0, -90.0f, 1, 0 }, 201 { 1, 0, -90.0f, 1, 0 },
195 { 1, 0, 90.0f, 0, 1 }, 202 { 1, 0, 90.0f, 0, 1 },
196 { 1, 0, 360.0f, 0, 1 }, 203 { 1, 0, 360.0f, 0, 1 },
197 { 1, 0, 0.0f, 0, 1 }, 204 { 1, 0, 0.0f, 0, 1 },
198 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0 } 205 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0 }
199 }; 206 };
200 207
201 Transform xform; 208 Transform xform;
202 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 209 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
203 const TestCase& value = test_cases[i]; 210 const TestCase& value = test_cases[i];
204 xform.ConcatRotate(value.degrees); 211 Transform rotation;
212 rotation.Rotate(value.degrees);
213 xform = rotation * xform;
205 Point3F p1(value.x1, value.y1, 0); 214 Point3F p1(value.x1, value.y1, 0);
206 Point3F p2(value.x2, value.y2, 0); 215 Point3F p2(value.x2, value.y2, 0);
207 xform.TransformPoint(p1); 216 xform.TransformPoint(p1);
208 if (value.degrees == value.degrees) { 217 if (value.degrees == value.degrees) {
209 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 218 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
210 } 219 }
211 } 220 }
212 } 221 }
213 222
214 TEST(XFormTest, SetTranslate) { 223 TEST(XFormTest, SetTranslate) {
(...skipping 13 matching lines...) Expand all
228 237
229 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 238 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
230 const TestCase& value = test_cases[i]; 239 const TestCase& value = test_cases[i];
231 for (int k = 0; k < 3; ++k) { 240 for (int k = 0; k < 3; ++k) {
232 Point3F p0, p1, p2; 241 Point3F p0, p1, p2;
233 Transform xform; 242 Transform xform;
234 switch (k) { 243 switch (k) {
235 case 0: 244 case 0:
236 p1.SetPoint(value.x1, 0, 0); 245 p1.SetPoint(value.x1, 0, 0);
237 p2.SetPoint(value.x2, 0, 0); 246 p2.SetPoint(value.x2, 0, 0);
238 xform.SetTranslateX(value.tx); 247 xform.Translate(value.tx, 0.0);
239 break; 248 break;
240 case 1: 249 case 1:
241 p1.SetPoint(0, value.y1, 0); 250 p1.SetPoint(0, value.y1, 0);
242 p2.SetPoint(0, value.y2, 0); 251 p2.SetPoint(0, value.y2, 0);
243 xform.SetTranslateY(value.ty); 252 xform.Translate(0.0, value.ty);
244 break; 253 break;
245 case 2: 254 case 2:
246 p1.SetPoint(value.x1, value.y1, 0); 255 p1.SetPoint(value.x1, value.y1, 0);
247 p2.SetPoint(value.x2, value.y2, 0); 256 p2.SetPoint(value.x2, value.y2, 0);
248 xform.SetTranslate(value.tx, value.ty); 257 xform.Translate(value.tx, value.ty);
249 break; 258 break;
250 } 259 }
251 p0 = p1; 260 p0 = p1;
252 xform.TransformPoint(p1); 261 xform.TransformPoint(p1);
253 if (value.tx == value.tx && 262 if (value.tx == value.tx &&
254 value.ty == value.ty) { 263 value.ty == value.ty) {
255 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 264 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
256 xform.TransformPointReverse(p1); 265 xform.TransformPointReverse(p1);
257 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); 266 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
258 } 267 }
(...skipping 16 matching lines...) Expand all
275 284
276 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 285 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
277 const TestCase& value = test_cases[i]; 286 const TestCase& value = test_cases[i];
278 for (int k = 0; k < 3; ++k) { 287 for (int k = 0; k < 3; ++k) {
279 Point3F p0, p1, p2; 288 Point3F p0, p1, p2;
280 Transform xform; 289 Transform xform;
281 switch (k) { 290 switch (k) {
282 case 0: 291 case 0:
283 p1.SetPoint(value.before, 0, 0); 292 p1.SetPoint(value.before, 0, 0);
284 p2.SetPoint(value.after, 0, 0); 293 p2.SetPoint(value.after, 0, 0);
285 xform.SetScaleX(value.s); 294 xform.Scale(value.s, 1.0);
286 break; 295 break;
287 case 1: 296 case 1:
288 p1.SetPoint(0, value.before, 0); 297 p1.SetPoint(0, value.before, 0);
289 p2.SetPoint(0, value.after, 0); 298 p2.SetPoint(0, value.after, 0);
290 xform.SetScaleY(value.s); 299 xform.Scale(1.0, value.s);
291 break; 300 break;
292 case 2: 301 case 2:
293 p1.SetPoint(value.before, value.before, 0); 302 p1.SetPoint(value.before, value.before, 0);
294 p2.SetPoint(value.after, value.after, 0); 303 p2.SetPoint(value.after, value.after, 0);
295 xform.SetScale(value.s, value.s); 304 xform.Scale(value.s, value.s);
296 break; 305 break;
297 } 306 }
298 p0 = p1; 307 p0 = p1;
299 xform.TransformPoint(p1); 308 xform.TransformPoint(p1);
300 if (value.s == value.s) { 309 if (value.s == value.s) {
301 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 310 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
302 if (value.s != 0.0f) { 311 if (value.s != 0.0f) {
303 xform.TransformPointReverse(p1); 312 xform.TransformPointReverse(p1);
304 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); 313 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
305 } 314 }
(...skipping 20 matching lines...) Expand all
326 { 100, 0, 360.0f, 100, 0 } 335 { 100, 0, 360.0f, 100, 0 }
327 }; 336 };
328 337
329 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { 338 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) {
330 const SetRotateCase& value = set_rotate_cases[i]; 339 const SetRotateCase& value = set_rotate_cases[i];
331 Point3F p0; 340 Point3F p0;
332 Point3F p1(value.x, value.y, 0); 341 Point3F p1(value.x, value.y, 0);
333 Point3F p2(value.xprime, value.yprime, 0); 342 Point3F p2(value.xprime, value.yprime, 0);
334 p0 = p1; 343 p0 = p1;
335 Transform xform; 344 Transform xform;
336 xform.SetRotate(value.degree); 345 xform.Rotate(value.degree);
337 // just want to make sure that we don't crash in the case of NaN. 346 // just want to make sure that we don't crash in the case of NaN.
338 if (value.degree == value.degree) { 347 if (value.degree == value.degree) {
339 xform.TransformPoint(p1); 348 xform.TransformPoint(p1);
340 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2)); 349 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
341 xform.TransformPointReverse(p1); 350 xform.TransformPointReverse(p1);
342 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0)); 351 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
343 } 352 }
344 } 353 }
345 } 354 }
346 355
(...skipping 12 matching lines...) Expand all
359 { 0, 0, -10.0f, -20.0f, -10, -20}, 368 { 0, 0, -10.0f, -20.0f, -10, -20},
360 { 0, 0, 369 { 0, 0,
361 std::numeric_limits<float>::quiet_NaN(), 370 std::numeric_limits<float>::quiet_NaN(),
362 std::numeric_limits<float>::quiet_NaN(), 371 std::numeric_limits<float>::quiet_NaN(),
363 10, 20}, 372 10, 20},
364 }; 373 };
365 374
366 Transform xform; 375 Transform xform;
367 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 376 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
368 const TestCase& value = test_cases[i]; 377 const TestCase& value = test_cases[i];
369 xform.ConcatTranslate(value.tx, value.ty); 378 Transform translation;
379 translation.Translate(value.tx, value.ty);
380 xform = translation * xform;
370 Point p1(value.x1, value.y1); 381 Point p1(value.x1, value.y1);
371 Point p2(value.x2, value.y2); 382 Point p2(value.x2, value.y2);
372 xform.TransformPoint(p1); 383 xform.TransformPoint(p1);
373 if (value.tx == value.tx && 384 if (value.tx == value.tx &&
374 value.ty == value.ty) { 385 value.ty == value.ty) {
375 EXPECT_EQ(p1.x(), p2.x()); 386 EXPECT_EQ(p1.x(), p2.x());
376 EXPECT_EQ(p1.y(), p2.y()); 387 EXPECT_EQ(p1.y(), p2.y());
377 } 388 }
378 } 389 }
379 } 390 }
380 391
381 TEST(XFormTest, ConcatScale2D) { 392 TEST(XFormTest, ConcatScale2D) {
382 static const struct TestCase { 393 static const struct TestCase {
383 int before; 394 int before;
384 float scale; 395 float scale;
385 int after; 396 int after;
386 } test_cases[] = { 397 } test_cases[] = {
387 { 1, 10.0f, 10}, 398 { 1, 10.0f, 10},
388 { 1, .1f, 1}, 399 { 1, .1f, 1},
389 { 1, 100.0f, 100}, 400 { 1, 100.0f, 100},
390 { 1, -1.0f, -100}, 401 { 1, -1.0f, -100},
391 { 1, std::numeric_limits<float>::quiet_NaN(), 1} 402 { 1, std::numeric_limits<float>::quiet_NaN(), 1}
392 }; 403 };
393 404
394 Transform xform; 405 Transform xform;
395 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 406 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
396 const TestCase& value = test_cases[i]; 407 const TestCase& value = test_cases[i];
397 xform.ConcatScale(value.scale, value.scale); 408 Transform scale;
409 scale.Scale(value.scale, value.scale);
410 xform = scale * xform;
398 Point p1(value.before, value.before); 411 Point p1(value.before, value.before);
399 Point p2(value.after, value.after); 412 Point p2(value.after, value.after);
400 xform.TransformPoint(p1); 413 xform.TransformPoint(p1);
401 if (value.scale == value.scale) { 414 if (value.scale == value.scale) {
402 EXPECT_EQ(p1.x(), p2.x()); 415 EXPECT_EQ(p1.x(), p2.x());
403 EXPECT_EQ(p1.y(), p2.y()); 416 EXPECT_EQ(p1.y(), p2.y());
404 } 417 }
405 } 418 }
406 } 419 }
407 420
408 TEST(XFormTest, ConcatRotate2D) { 421 TEST(XFormTest, ConcatRotate2D) {
409 static const struct TestCase { 422 static const struct TestCase {
410 int x1; 423 int x1;
411 int y1; 424 int y1;
412 float degrees; 425 float degrees;
413 int x2; 426 int x2;
414 int y2; 427 int y2;
415 } test_cases[] = { 428 } test_cases[] = {
416 { 1, 0, 90.0f, 0, 1}, 429 { 1, 0, 90.0f, 0, 1},
417 { 1, 0, -90.0f, 1, 0}, 430 { 1, 0, -90.0f, 1, 0},
418 { 1, 0, 90.0f, 0, 1}, 431 { 1, 0, 90.0f, 0, 1},
419 { 1, 0, 360.0f, 0, 1}, 432 { 1, 0, 360.0f, 0, 1},
420 { 1, 0, 0.0f, 0, 1}, 433 { 1, 0, 0.0f, 0, 1},
421 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0} 434 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0}
422 }; 435 };
423 436
424 Transform xform; 437 Transform xform;
425 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 438 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
426 const TestCase& value = test_cases[i]; 439 const TestCase& value = test_cases[i];
427 xform.ConcatRotate(value.degrees); 440 Transform rotation;
441 rotation.Rotate(value.degrees);
442 xform = rotation * xform;
428 Point p1(value.x1, value.y1); 443 Point p1(value.x1, value.y1);
429 Point p2(value.x2, value.y2); 444 Point p2(value.x2, value.y2);
430 xform.TransformPoint(p1); 445 xform.TransformPoint(p1);
431 if (value.degrees == value.degrees) { 446 if (value.degrees == value.degrees) {
432 EXPECT_EQ(p1.x(), p2.x()); 447 EXPECT_EQ(p1.x(), p2.x());
433 EXPECT_EQ(p1.y(), p2.y()); 448 EXPECT_EQ(p1.y(), p2.y());
434 } 449 }
435 } 450 }
436 } 451 }
437 452
(...skipping 16 matching lines...) Expand all
454 const TestCase& value = test_cases[i]; 469 const TestCase& value = test_cases[i];
455 for (int j = -1; j < 2; ++j) { 470 for (int j = -1; j < 2; ++j) {
456 for (int k = 0; k < 3; ++k) { 471 for (int k = 0; k < 3; ++k) {
457 float epsilon = 0.0001f; 472 float epsilon = 0.0001f;
458 Point p0, p1, p2; 473 Point p0, p1, p2;
459 Transform xform; 474 Transform xform;
460 switch (k) { 475 switch (k) {
461 case 0: 476 case 0:
462 p1.SetPoint(value.x1, 0); 477 p1.SetPoint(value.x1, 0);
463 p2.SetPoint(value.x2, 0); 478 p2.SetPoint(value.x2, 0);
464 xform.SetTranslateX(value.tx + j * epsilon); 479 xform.Translate(value.tx + j * epsilon, 0.0);
465 break; 480 break;
466 case 1: 481 case 1:
467 p1.SetPoint(0, value.y1); 482 p1.SetPoint(0, value.y1);
468 p2.SetPoint(0, value.y2); 483 p2.SetPoint(0, value.y2);
469 xform.SetTranslateY(value.ty + j * epsilon); 484 xform.Translate(0.0, value.ty + j * epsilon);
470 break; 485 break;
471 case 2: 486 case 2:
472 p1.SetPoint(value.x1, value.y1); 487 p1.SetPoint(value.x1, value.y1);
473 p2.SetPoint(value.x2, value.y2); 488 p2.SetPoint(value.x2, value.y2);
474 xform.SetTranslate(value.tx + j * epsilon, 489 xform.Translate(value.tx + j * epsilon,
475 value.ty + j * epsilon); 490 value.ty + j * epsilon);
476 break; 491 break;
477 } 492 }
478 p0 = p1; 493 p0 = p1;
479 xform.TransformPoint(p1); 494 xform.TransformPoint(p1);
480 if (value.tx == value.tx && 495 if (value.tx == value.tx &&
481 value.ty == value.ty) { 496 value.ty == value.ty) {
482 EXPECT_EQ(p1.x(), p2.x()); 497 EXPECT_EQ(p1.x(), p2.x());
483 EXPECT_EQ(p1.y(), p2.y()); 498 EXPECT_EQ(p1.y(), p2.y());
484 xform.TransformPointReverse(p1); 499 xform.TransformPointReverse(p1);
485 EXPECT_EQ(p1.x(), p0.x()); 500 EXPECT_EQ(p1.x(), p0.x());
(...skipping 21 matching lines...) Expand all
507 const TestCase& value = test_cases[i]; 522 const TestCase& value = test_cases[i];
508 for (int j = -1; j < 2; ++j) { 523 for (int j = -1; j < 2; ++j) {
509 for (int k = 0; k < 3; ++k) { 524 for (int k = 0; k < 3; ++k) {
510 float epsilon = 0.0001f; 525 float epsilon = 0.0001f;
511 Point p0, p1, p2; 526 Point p0, p1, p2;
512 Transform xform; 527 Transform xform;
513 switch (k) { 528 switch (k) {
514 case 0: 529 case 0:
515 p1.SetPoint(value.before, 0); 530 p1.SetPoint(value.before, 0);
516 p2.SetPoint(value.after, 0); 531 p2.SetPoint(value.after, 0);
517 xform.SetScaleX(value.s + j * epsilon); 532 xform.Scale(value.s + j * epsilon, 1.0);
518 break; 533 break;
519 case 1: 534 case 1:
520 p1.SetPoint(0, value.before); 535 p1.SetPoint(0, value.before);
521 p2.SetPoint(0, value.after); 536 p2.SetPoint(0, value.after);
522 xform.SetScaleY(value.s + j * epsilon); 537 xform.Scale(1.0, value.s + j * epsilon);
523 break; 538 break;
524 case 2: 539 case 2:
525 p1.SetPoint(value.before, 540 p1.SetPoint(value.before,
526 value.before); 541 value.before);
527 p2.SetPoint(value.after, 542 p2.SetPoint(value.after,
528 value.after); 543 value.after);
529 xform.SetScale(value.s + j * epsilon, 544 xform.Scale(value.s + j * epsilon,
530 value.s + j * epsilon); 545 value.s + j * epsilon);
531 break; 546 break;
532 } 547 }
533 p0 = p1; 548 p0 = p1;
534 xform.TransformPoint(p1); 549 xform.TransformPoint(p1);
535 if (value.s == value.s) { 550 if (value.s == value.s) {
536 EXPECT_EQ(p1.x(), p2.x()); 551 EXPECT_EQ(p1.x(), p2.x());
537 EXPECT_EQ(p1.y(), p2.y()); 552 EXPECT_EQ(p1.y(), p2.y());
538 if (value.s != 0.0f) { 553 if (value.s != 0.0f) {
539 xform.TransformPointReverse(p1); 554 xform.TransformPointReverse(p1);
540 EXPECT_EQ(p1.x(), p0.x()); 555 EXPECT_EQ(p1.x(), p0.x());
(...skipping 23 matching lines...) Expand all
564 { 100, 0, 360.0f, 100, 0} 579 { 100, 0, 360.0f, 100, 0}
565 }; 580 };
566 581
567 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) { 582 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) {
568 const SetRotateCase& value = set_rotate_cases[i]; 583 const SetRotateCase& value = set_rotate_cases[i];
569 for (int j = 1; j >= -1; --j) { 584 for (int j = 1; j >= -1; --j) {
570 float epsilon = 0.1f; 585 float epsilon = 0.1f;
571 Point pt(value.x, value.y); 586 Point pt(value.x, value.y);
572 Transform xform; 587 Transform xform;
573 // should be invariant to small floating point errors. 588 // should be invariant to small floating point errors.
574 xform.SetRotate(value.degree + j * epsilon); 589 xform.Rotate(value.degree + j * epsilon);
575 // just want to make sure that we don't crash in the case of NaN. 590 // just want to make sure that we don't crash in the case of NaN.
576 if (value.degree == value.degree) { 591 if (value.degree == value.degree) {
577 xform.TransformPoint(pt); 592 xform.TransformPoint(pt);
578 EXPECT_EQ(value.xprime, pt.x()); 593 EXPECT_EQ(value.xprime, pt.x());
579 EXPECT_EQ(value.yprime, pt.y()); 594 EXPECT_EQ(value.yprime, pt.y());
580 xform.TransformPointReverse(pt); 595 xform.TransformPointReverse(pt);
581 EXPECT_EQ(pt.x(), value.x); 596 EXPECT_EQ(pt.x(), value.x);
582 EXPECT_EQ(pt.y(), value.y); 597 EXPECT_EQ(pt.y(), value.y);
583 } 598 }
584 } 599 }
585 } 600 }
586 } 601 }
587 602
588 TEST(XFormTest, BlendTranslate) { 603 TEST(XFormTest, BlendTranslate) {
589 Transform from; 604 Transform from;
590 for (int i = 0; i < 10; ++i) { 605 for (int i = 0; i < 10; ++i) {
591 Transform to; 606 Transform to;
592 to.SetTranslate3d(1, 1, 1); 607 to.Translate3d(1, 1, 1);
593 double t = i / 9.0; 608 double t = i / 9.0;
594 EXPECT_TRUE(to.Blend(from, t)); 609 EXPECT_TRUE(to.Blend(from, t));
595 EXPECT_FLOAT_EQ(t, to.matrix().get(0, 3)); 610 EXPECT_FLOAT_EQ(t, to.matrix().get(0, 3));
596 EXPECT_FLOAT_EQ(t, to.matrix().get(1, 3)); 611 EXPECT_FLOAT_EQ(t, to.matrix().get(1, 3));
597 EXPECT_FLOAT_EQ(t, to.matrix().get(2, 3)); 612 EXPECT_FLOAT_EQ(t, to.matrix().get(2, 3));
598 } 613 }
599 } 614 }
600 615
601 TEST(XFormTest, BlendRotate) { 616 TEST(XFormTest, BlendRotate) {
602 Point3F axes[] = { 617 Vector3dF axes[] = {
603 Point3F(1, 0, 0), 618 Vector3dF(1, 0, 0),
604 Point3F(0, 1, 0), 619 Vector3dF(0, 1, 0),
605 Point3F(0, 0, 1), 620 Vector3dF(0, 0, 1),
606 Point3F(1, 1, 1) 621 Vector3dF(1, 1, 1)
607 }; 622 };
608 Transform from; 623 Transform from;
609 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { 624 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) {
610 for (int i = 0; i < 10; ++i) { 625 for (int i = 0; i < 10; ++i) {
611 Transform to; 626 Transform to;
612 to.SetRotateAbout(axes[index], 90); 627 to.RotateAbout(axes[index], 90);
613 double t = i / 9.0; 628 double t = i / 9.0;
614 EXPECT_TRUE(to.Blend(from, t)); 629 EXPECT_TRUE(to.Blend(from, t));
615 630
616 Transform expected; 631 Transform expected;
617 expected.SetRotateAbout(axes[index], 90 * t); 632 expected.RotateAbout(axes[index], 90 * t);
618 633
619 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); 634 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to));
620 } 635 }
621 } 636 }
622 } 637 }
623 638
624 TEST(XFormTest, CannotBlend180DegreeRotation) { 639 TEST(XFormTest, CannotBlend180DegreeRotation) {
625 Point3F axes[] = { 640 Vector3dF axes[] = {
626 Point3F(1, 0, 0), 641 Vector3dF(1, 0, 0),
627 Point3F(0, 1, 0), 642 Vector3dF(0, 1, 0),
628 Point3F(0, 0, 1), 643 Vector3dF(0, 0, 1),
629 Point3F(1, 1, 1) 644 Vector3dF(1, 1, 1)
630 }; 645 };
631 Transform from; 646 Transform from;
632 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) { 647 for (size_t index = 0; index < ARRAYSIZE_UNSAFE(axes); ++index) {
633 Transform to; 648 Transform to;
634 to.SetRotateAbout(axes[index], 180); 649 to.RotateAbout(axes[index], 180);
635 EXPECT_FALSE(to.Blend(from, 0.5)); 650 EXPECT_FALSE(to.Blend(from, 0.5));
636 } 651 }
637 } 652 }
638 653
639 TEST(XFormTest, BlendScale) { 654 TEST(XFormTest, BlendScale) {
640 Transform from; 655 Transform from;
641 for (int i = 0; i < 10; ++i) { 656 for (int i = 0; i < 10; ++i) {
642 Transform to; 657 Transform to;
643 to.SetScale3d(5, 4, 3); 658 to.Scale3d(5, 4, 3);
644 double t = i / 9.0; 659 double t = i / 9.0;
645 EXPECT_TRUE(to.Blend(from, t)); 660 EXPECT_TRUE(to.Blend(from, t));
646 EXPECT_FLOAT_EQ(t * 4 + 1, to.matrix().get(0, 0)); 661 EXPECT_FLOAT_EQ(t * 4 + 1, to.matrix().get(0, 0));
647 EXPECT_FLOAT_EQ(t * 3 + 1, to.matrix().get(1, 1)); 662 EXPECT_FLOAT_EQ(t * 3 + 1, to.matrix().get(1, 1));
648 EXPECT_FLOAT_EQ(t * 2 + 1, to.matrix().get(2, 2)); 663 EXPECT_FLOAT_EQ(t * 2 + 1, to.matrix().get(2, 2));
649 } 664 }
650 } 665 }
651 666
652 TEST(XFormTest, BlendSkew) { 667 TEST(XFormTest, BlendSkew) {
653 Transform from; 668 Transform from;
654 for (int i = 0; i < 2; ++i) { 669 for (int i = 0; i < 2; ++i) {
655 Transform to; 670 Transform to;
656 to.SetSkewX(20); 671 to.SkewX(20);
657 to.PreconcatSkewY(10); 672 to.SkewY(10);
658 double t = i; 673 double t = i;
659 Transform expected; 674 Transform expected;
660 expected.SetSkewX(t * 20); 675 expected.SkewX(t * 20);
661 expected.PreconcatSkewY(t * 10); 676 expected.SkewY(t * 10);
662 EXPECT_TRUE(to.Blend(from, t)); 677 EXPECT_TRUE(to.Blend(from, t));
663 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); 678 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to));
664 } 679 }
665 } 680 }
666 681
667 TEST(XFormTest, BlendPerspective) { 682 TEST(XFormTest, BlendPerspective) {
668 Transform from; 683 Transform from;
669 from.SetPerspectiveDepth(200); 684 from.ApplyPerspectiveDepth(200);
670 for (int i = 0; i < 2; ++i) { 685 for (int i = 0; i < 2; ++i) {
671 Transform to; 686 Transform to;
672 to.SetPerspectiveDepth(800); 687 to.ApplyPerspectiveDepth(800);
673 double t = i; 688 double t = i;
674 Transform expected; 689 Transform expected;
675 expected.SetPerspectiveDepth(t * 600 + 200); 690 expected.ApplyPerspectiveDepth(t * 600 + 200);
676 EXPECT_TRUE(to.Blend(from, t)); 691 EXPECT_TRUE(to.Blend(from, t));
677 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to)); 692 EXPECT_TRUE(MatricesAreNearlyEqual(expected, to));
678 } 693 }
679 } 694 }
680 695
681 TEST(XFormTest, BlendIdentity) { 696 TEST(XFormTest, BlendIdentity) {
682 Transform from; 697 Transform from;
683 Transform to; 698 Transform to;
684 EXPECT_TRUE(to.Blend(from, 0.5)); 699 EXPECT_TRUE(to.Blend(from, 0.5));
685 EXPECT_EQ(to, from); 700 EXPECT_EQ(to, from);
686 } 701 }
687 702
688 TEST(XFormTest, CannotBlendSingularMatrix) { 703 TEST(XFormTest, CannotBlendSingularMatrix) {
689 Transform from; 704 Transform from;
690 Transform to; 705 Transform to;
691 to.matrix().set(1, 1, SkDoubleToMScalar(0)); 706 to.matrix().set(1, 1, SkDoubleToMScalar(0));
692 EXPECT_FALSE(to.Blend(from, 0.5)); 707 EXPECT_FALSE(to.Blend(from, 0.5));
693 } 708 }
694 709
695 TEST(XFormTest, VerifyBlendForTranslation) 710 TEST(XFormTest, VerifyBlendForTranslation)
696 { 711 {
697 Transform from; 712 Transform from;
698 from.PreconcatTranslate3d(100, 200, 100); 713 from.Translate3d(100, 200, 100);
699 714
700 Transform to; 715 Transform to;
701 716
702 to.PreconcatTranslate3d(200, 100, 300); 717 to.Translate3d(200, 100, 300);
703 to.Blend(from, 0); 718 to.Blend(from, 0);
704 EXPECT_EQ(from, to); 719 EXPECT_EQ(from, to);
705 720
706 to = Transform(); 721 to = Transform();
707 to.PreconcatTranslate3d(200, 100, 300); 722 to.Translate3d(200, 100, 300);
708 to.Blend(from, 0.25); 723 to.Blend(from, 0.25);
709 EXPECT_ROW1_EQ(1, 0, 0, 125, to); 724 EXPECT_ROW1_EQ(1, 0, 0, 125, to);
710 EXPECT_ROW2_EQ(0, 1, 0, 175, to); 725 EXPECT_ROW2_EQ(0, 1, 0, 175, to);
711 EXPECT_ROW3_EQ(0, 0, 1, 150, to); 726 EXPECT_ROW3_EQ(0, 0, 1, 150, to);
712 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 727 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
713 728
714 to = Transform(); 729 to = Transform();
715 to.PreconcatTranslate3d(200, 100, 300); 730 to.Translate3d(200, 100, 300);
716 to.Blend(from, 0.5); 731 to.Blend(from, 0.5);
717 EXPECT_ROW1_EQ(1, 0, 0, 150, to); 732 EXPECT_ROW1_EQ(1, 0, 0, 150, to);
718 EXPECT_ROW2_EQ(0, 1, 0, 150, to); 733 EXPECT_ROW2_EQ(0, 1, 0, 150, to);
719 EXPECT_ROW3_EQ(0, 0, 1, 200, to); 734 EXPECT_ROW3_EQ(0, 0, 1, 200, to);
720 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 735 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
721 736
722 to = Transform(); 737 to = Transform();
723 to.PreconcatTranslate3d(200, 100, 300); 738 to.Translate3d(200, 100, 300);
724 to.Blend(from, 1); 739 to.Blend(from, 1);
725 EXPECT_ROW1_EQ(1, 0, 0, 200, to); 740 EXPECT_ROW1_EQ(1, 0, 0, 200, to);
726 EXPECT_ROW2_EQ(0, 1, 0, 100, to); 741 EXPECT_ROW2_EQ(0, 1, 0, 100, to);
727 EXPECT_ROW3_EQ(0, 0, 1, 300, to); 742 EXPECT_ROW3_EQ(0, 0, 1, 300, to);
728 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 743 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
729 } 744 }
730 745
731 TEST(XFormTest, VerifyBlendForScale) 746 TEST(XFormTest, VerifyBlendForScale)
732 { 747 {
733 Transform from; 748 Transform from;
734 from.PreconcatScale3d(100, 200, 100); 749 from.Scale3d(100, 200, 100);
735 750
736 Transform to; 751 Transform to;
737 752
738 to.PreconcatScale3d(200, 100, 300); 753 to.Scale3d(200, 100, 300);
739 to.Blend(from, 0); 754 to.Blend(from, 0);
740 EXPECT_EQ(from, to); 755 EXPECT_EQ(from, to);
741 756
742 to = Transform(); 757 to = Transform();
743 to.PreconcatScale3d(200, 100, 300); 758 to.Scale3d(200, 100, 300);
744 to.Blend(from, 0.25); 759 to.Blend(from, 0.25);
745 EXPECT_ROW1_EQ(125, 0, 0, 0, to); 760 EXPECT_ROW1_EQ(125, 0, 0, 0, to);
746 EXPECT_ROW2_EQ(0, 175, 0, 0, to); 761 EXPECT_ROW2_EQ(0, 175, 0, 0, to);
747 EXPECT_ROW3_EQ(0, 0, 150, 0, to); 762 EXPECT_ROW3_EQ(0, 0, 150, 0, to);
748 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 763 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
749 764
750 to = Transform(); 765 to = Transform();
751 to.PreconcatScale3d(200, 100, 300); 766 to.Scale3d(200, 100, 300);
752 to.Blend(from, 0.5); 767 to.Blend(from, 0.5);
753 EXPECT_ROW1_EQ(150, 0, 0, 0, to); 768 EXPECT_ROW1_EQ(150, 0, 0, 0, to);
754 EXPECT_ROW2_EQ(0, 150, 0, 0, to); 769 EXPECT_ROW2_EQ(0, 150, 0, 0, to);
755 EXPECT_ROW3_EQ(0, 0, 200, 0, to); 770 EXPECT_ROW3_EQ(0, 0, 200, 0, to);
756 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 771 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
757 772
758 to = Transform(); 773 to = Transform();
759 to.PreconcatScale3d(200, 100, 300); 774 to.Scale3d(200, 100, 300);
760 to.Blend(from, 1); 775 to.Blend(from, 1);
761 EXPECT_ROW1_EQ(200, 0, 0, 0, to); 776 EXPECT_ROW1_EQ(200, 0, 0, 0, to);
762 EXPECT_ROW2_EQ(0, 100, 0, 0, to); 777 EXPECT_ROW2_EQ(0, 100, 0, 0, to);
763 EXPECT_ROW3_EQ(0, 0, 300, 0, to); 778 EXPECT_ROW3_EQ(0, 0, 300, 0, to);
764 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 779 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
765 } 780 }
766 781
767 TEST(XFormTest, VerifyBlendForSkewX) 782 TEST(XFormTest, VerifyBlendForSkewX)
768 { 783 {
769 Transform from; 784 Transform from;
770 from.PreconcatSkewX(0); 785 from.SkewX(0);
771 786
772 Transform to; 787 Transform to;
773 788
774 to.PreconcatSkewX(45); 789 to.SkewX(45);
775 to.Blend(from, 0); 790 to.Blend(from, 0);
776 EXPECT_EQ(from, to); 791 EXPECT_EQ(from, to);
777 792
778 to = Transform(); 793 to = Transform();
779 to.PreconcatSkewX(45); 794 to.SkewX(45);
780 to.Blend(from, 0.5); 795 to.Blend(from, 0.5);
781 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to); 796 EXPECT_ROW1_EQ(1, 0.5, 0, 0, to);
782 EXPECT_ROW2_EQ(0, 1, 0, 0, to); 797 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
783 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 798 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
784 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 799 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
785 800
786 to = Transform(); 801 to = Transform();
787 to.PreconcatSkewX(45); 802 to.SkewX(45);
788 to.Blend(from, 0.25); 803 to.Blend(from, 0.25);
789 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to); 804 EXPECT_ROW1_EQ(1, 0.25, 0, 0, to);
790 EXPECT_ROW2_EQ(0, 1, 0, 0, to); 805 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
791 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 806 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
792 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 807 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
793 808
794 to = Transform(); 809 to = Transform();
795 to.PreconcatSkewX(45); 810 to.SkewX(45);
796 to.Blend(from, 1); 811 to.Blend(from, 1);
797 EXPECT_ROW1_EQ(1, 1, 0, 0, to); 812 EXPECT_ROW1_EQ(1, 1, 0, 0, to);
798 EXPECT_ROW2_EQ(0, 1, 0, 0, to); 813 EXPECT_ROW2_EQ(0, 1, 0, 0, to);
799 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 814 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
800 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 815 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
801 } 816 }
802 817
803 TEST(XFormTest, VerifyBlendForSkewY) 818 TEST(XFormTest, VerifyBlendForSkewY)
804 { 819 {
805 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix 820 // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix
806 // is inherently underconstrained, and so it does not always compute the 821 // is inherently underconstrained, and so it does not always compute the
807 // originally intended skew parameters. The current implementation uses QR 822 // originally intended skew parameters. The current implementation uses QR
808 // decomposition, which decomposes the shear into a rotation + non-uniform 823 // decomposition, which decomposes the shear into a rotation + non-uniform
809 // scale. 824 // scale.
810 // 825 //
811 // It is unlikely that the decomposition implementation will need to change 826 // It is unlikely that the decomposition implementation will need to change
812 // very often, so to get any test coverage, the compromise is to verify the 827 // very often, so to get any test coverage, the compromise is to verify the
813 // exact matrix that the.Blend() operation produces. 828 // exact matrix that the.Blend() operation produces.
814 // 829 //
815 // This problem also potentially exists for skewX, but the current QR 830 // This problem also potentially exists for skewX, but the current QR
816 // decomposition implementation just happens to decompose those test 831 // decomposition implementation just happens to decompose those test
817 // matrices intuitively. 832 // matrices intuitively.
818 // 833 //
819 // Unfortunately, this case suffers from uncomfortably large precision 834 // Unfortunately, this case suffers from uncomfortably large precision
820 // error. 835 // error.
821 836
822 Transform from; 837 Transform from;
823 from.PreconcatSkewY(0); 838 from.SkewY(0);
824 839
825 Transform to; 840 Transform to;
826 841
827 to.PreconcatSkewY(45); 842 to.SkewY(45);
828 to.Blend(from, 0); 843 to.Blend(from, 0);
829 EXPECT_EQ(from, to); 844 EXPECT_EQ(from, to);
830 845
831 to = Transform(); 846 to = Transform();
832 to.PreconcatSkewY(45); 847 to.SkewY(45);
833 to.Blend(from, 0.25); 848 to.Blend(from, 0.25);
834 EXPECT_ROW1_NEAR(1.0823489449280947471976333, 849 EXPECT_ROW1_NEAR(1.0823489449280947471976333,
835 0.0464370719145053845178239, 850 0.0464370719145053845178239,
836 0, 851 0,
837 0, 852 0,
838 to, 853 to,
839 LOOSE_ERROR_THRESHOLD); 854 LOOSE_ERROR_THRESHOLD);
840 EXPECT_ROW2_NEAR(0.2152925909665224513123150, 855 EXPECT_ROW2_NEAR(0.2152925909665224513123150,
841 0.9541702441750861130032035, 856 0.9541702441750861130032035,
842 0, 857 0,
843 0, 858 0,
844 to, 859 to,
845 LOOSE_ERROR_THRESHOLD); 860 LOOSE_ERROR_THRESHOLD);
846 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 861 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
847 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 862 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
848 863
849 to = Transform(); 864 to = Transform();
850 to.PreconcatSkewY(45); 865 to.SkewY(45);
851 to.Blend(from, 0.5); 866 to.Blend(from, 0.5);
852 EXPECT_ROW1_NEAR(1.1152212925809066312865525, 867 EXPECT_ROW1_NEAR(1.1152212925809066312865525,
853 0.0676495144007326631996335, 868 0.0676495144007326631996335,
854 0, 869 0,
855 0, 870 0,
856 to, 871 to,
857 LOOSE_ERROR_THRESHOLD); 872 LOOSE_ERROR_THRESHOLD);
858 EXPECT_ROW2_NEAR(0.4619397844342648662419037, 873 EXPECT_ROW2_NEAR(0.4619397844342648662419037,
859 0.9519009045724774464858342, 874 0.9519009045724774464858342,
860 0, 875 0,
861 0, 876 0,
862 to, 877 to,
863 LOOSE_ERROR_THRESHOLD); 878 LOOSE_ERROR_THRESHOLD);
864 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 879 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
865 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 880 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
866 881
867 to = Transform(); 882 to = Transform();
868 to.PreconcatSkewY(45); 883 to.SkewY(45);
869 to.Blend(from, 1); 884 to.Blend(from, 1);
870 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD); 885 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD);
871 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD); 886 EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD);
872 EXPECT_ROW3_EQ(0, 0, 1, 0, to); 887 EXPECT_ROW3_EQ(0, 0, 1, 0, to);
873 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 888 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
874 } 889 }
875 890
876 TEST(XFormTest, VerifyBlendForRotationAboutX) 891 TEST(XFormTest, VerifyBlendForRotationAboutX)
877 { 892 {
878 // Even though.Blending uses quaternions, axis-aligned rotations should. 893 // Even though.Blending uses quaternions, axis-aligned rotations should.
879 // Blend the same with quaternions or Euler angles. So we can test 894 // Blend the same with quaternions or Euler angles. So we can test
880 // rotation.Blending by comparing against manually specified matrices from 895 // rotation.Blending by comparing against manually specified matrices from
881 // Euler angles. 896 // Euler angles.
882 897
883 Transform from; 898 Transform from;
884 from.PreconcatRotateAbout(Point3F(1, 0, 0), 0); 899 from.RotateAbout(Vector3dF(1, 0, 0), 0);
885 900
886 Transform to; 901 Transform to;
887 902
888 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); 903 to.RotateAbout(Vector3dF(1, 0, 0), 90);
889 to.Blend(from, 0); 904 to.Blend(from, 0);
890 EXPECT_EQ(from, to); 905 EXPECT_EQ(from, to);
891 906
892 double expectedRotationAngle = 22.5 * M_PI / 180.0; 907 double expectedRotationAngle = 22.5 * M_PI / 180.0;
893 to = Transform(); 908 to = Transform();
894 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); 909 to.RotateAbout(Vector3dF(1, 0, 0), 90);
895 to.Blend(from, 0.25); 910 to.Blend(from, 0.25);
896 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); 911 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
897 EXPECT_ROW2_NEAR(0, 912 EXPECT_ROW2_NEAR(0,
898 std::cos(expectedRotationAngle), 913 std::cos(expectedRotationAngle),
899 -std::sin(expectedRotationAngle), 914 -std::sin(expectedRotationAngle),
900 0, 915 0,
901 to, 916 to,
902 ERROR_THRESHOLD); 917 ERROR_THRESHOLD);
903 EXPECT_ROW3_NEAR(0, 918 EXPECT_ROW3_NEAR(0,
904 std::sin(expectedRotationAngle), 919 std::sin(expectedRotationAngle),
905 std::cos(expectedRotationAngle), 920 std::cos(expectedRotationAngle),
906 0, 921 0,
907 to, 922 to,
908 ERROR_THRESHOLD); 923 ERROR_THRESHOLD);
909 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 924 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
910 925
911 expectedRotationAngle = 45 * M_PI / 180.0; 926 expectedRotationAngle = 45 * M_PI / 180.0;
912 to = Transform(); 927 to = Transform();
913 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); 928 to.RotateAbout(Vector3dF(1, 0, 0), 90);
914 to.Blend(from, 0.5); 929 to.Blend(from, 0.5);
915 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); 930 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
916 EXPECT_ROW2_NEAR(0, 931 EXPECT_ROW2_NEAR(0,
917 std::cos(expectedRotationAngle), 932 std::cos(expectedRotationAngle),
918 -std::sin(expectedRotationAngle), 933 -std::sin(expectedRotationAngle),
919 0, 934 0,
920 to, 935 to,
921 ERROR_THRESHOLD); 936 ERROR_THRESHOLD);
922 EXPECT_ROW3_NEAR(0, 937 EXPECT_ROW3_NEAR(0,
923 std::sin(expectedRotationAngle), 938 std::sin(expectedRotationAngle),
924 std::cos(expectedRotationAngle), 939 std::cos(expectedRotationAngle),
925 0, 940 0,
926 to, 941 to,
927 ERROR_THRESHOLD); 942 ERROR_THRESHOLD);
928 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 943 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
929 944
930 to = Transform(); 945 to = Transform();
931 to.PreconcatRotateAbout(Point3F(1, 0, 0), 90); 946 to.RotateAbout(Vector3dF(1, 0, 0), 90);
932 to.Blend(from, 1); 947 to.Blend(from, 1);
933 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); 948 EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
934 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD); 949 EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD);
935 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); 950 EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
936 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 951 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
937 } 952 }
938 953
939 TEST(XFormTest, VerifyBlendForRotationAboutY) 954 TEST(XFormTest, VerifyBlendForRotationAboutY)
940 { 955 {
941 Transform from; 956 Transform from;
942 from.PreconcatRotateAbout(Point3F(0, 1, 0), 0); 957 from.RotateAbout(Vector3dF(0, 1, 0), 0);
943 958
944 Transform to; 959 Transform to;
945 960
946 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); 961 to.RotateAbout(Vector3dF(0, 1, 0), 90);
947 to.Blend(from, 0); 962 to.Blend(from, 0);
948 EXPECT_EQ(from, to); 963 EXPECT_EQ(from, to);
949 964
950 double expectedRotationAngle = 22.5 * M_PI / 180.0; 965 double expectedRotationAngle = 22.5 * M_PI / 180.0;
951 to = Transform(); 966 to = Transform();
952 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); 967 to.RotateAbout(Vector3dF(0, 1, 0), 90);
953 to.Blend(from, 0.25); 968 to.Blend(from, 0.25);
954 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 969 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
955 0, 970 0,
956 std::sin(expectedRotationAngle), 971 std::sin(expectedRotationAngle),
957 0, 972 0,
958 to, 973 to,
959 ERROR_THRESHOLD); 974 ERROR_THRESHOLD);
960 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); 975 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
961 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), 976 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle),
962 0, 977 0,
963 std::cos(expectedRotationAngle), 978 std::cos(expectedRotationAngle),
964 0, 979 0,
965 to, 980 to,
966 ERROR_THRESHOLD); 981 ERROR_THRESHOLD);
967 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 982 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
968 983
969 expectedRotationAngle = 45 * M_PI / 180.0; 984 expectedRotationAngle = 45 * M_PI / 180.0;
970 to = Transform(); 985 to = Transform();
971 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); 986 to.RotateAbout(Vector3dF(0, 1, 0), 90);
972 to.Blend(from, 0.5); 987 to.Blend(from, 0.5);
973 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 988 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
974 0, 989 0,
975 std::sin(expectedRotationAngle), 990 std::sin(expectedRotationAngle),
976 0, 991 0,
977 to, 992 to,
978 ERROR_THRESHOLD); 993 ERROR_THRESHOLD);
979 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); 994 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
980 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle), 995 EXPECT_ROW3_NEAR(-std::sin(expectedRotationAngle),
981 0, 996 0,
982 std::cos(expectedRotationAngle), 997 std::cos(expectedRotationAngle),
983 0, 998 0,
984 to, 999 to,
985 ERROR_THRESHOLD); 1000 ERROR_THRESHOLD);
986 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 1001 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
987 1002
988 to = Transform(); 1003 to = Transform();
989 to.PreconcatRotateAbout(Point3F(0, 1, 0), 90); 1004 to.RotateAbout(Vector3dF(0, 1, 0), 90);
990 to.Blend(from, 1); 1005 to.Blend(from, 1);
991 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); 1006 EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
992 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD); 1007 EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
993 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD); 1008 EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD);
994 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 1009 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
995 } 1010 }
996 1011
997 TEST(XFormTest, VerifyBlendForRotationAboutZ) 1012 TEST(XFormTest, VerifyBlendForRotationAboutZ)
998 { 1013 {
999 Transform from; 1014 Transform from;
1000 from.PreconcatRotateAbout(Point3F(0, 0, 1), 0); 1015 from.RotateAbout(Vector3dF(0, 0, 1), 0);
1001 1016
1002 Transform to; 1017 Transform to;
1003 1018
1004 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); 1019 to.RotateAbout(Vector3dF(0, 0, 1), 90);
1005 to.Blend(from, 0); 1020 to.Blend(from, 0);
1006 EXPECT_EQ(from, to); 1021 EXPECT_EQ(from, to);
1007 1022
1008 double expectedRotationAngle = 22.5 * M_PI / 180.0; 1023 double expectedRotationAngle = 22.5 * M_PI / 180.0;
1009 to = Transform(); 1024 to = Transform();
1010 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); 1025 to.RotateAbout(Vector3dF(0, 0, 1), 90);
1011 to.Blend(from, 0.25); 1026 to.Blend(from, 0.25);
1012 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 1027 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
1013 -std::sin(expectedRotationAngle), 1028 -std::sin(expectedRotationAngle),
1014 0, 1029 0,
1015 0, 1030 0,
1016 to, 1031 to,
1017 ERROR_THRESHOLD); 1032 ERROR_THRESHOLD);
1018 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), 1033 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
1019 std::cos(expectedRotationAngle), 1034 std::cos(expectedRotationAngle),
1020 0, 1035 0,
1021 0, 1036 0,
1022 to, 1037 to,
1023 ERROR_THRESHOLD); 1038 ERROR_THRESHOLD);
1024 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); 1039 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1025 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 1040 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1026 1041
1027 expectedRotationAngle = 45 * M_PI / 180.0; 1042 expectedRotationAngle = 45 * M_PI / 180.0;
1028 to = Transform(); 1043 to = Transform();
1029 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); 1044 to.RotateAbout(Vector3dF(0, 0, 1), 90);
1030 to.Blend(from, 0.5); 1045 to.Blend(from, 0.5);
1031 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle), 1046 EXPECT_ROW1_NEAR(std::cos(expectedRotationAngle),
1032 -std::sin(expectedRotationAngle), 1047 -std::sin(expectedRotationAngle),
1033 0, 1048 0,
1034 0, 1049 0,
1035 to, 1050 to,
1036 ERROR_THRESHOLD); 1051 ERROR_THRESHOLD);
1037 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle), 1052 EXPECT_ROW2_NEAR(std::sin(expectedRotationAngle),
1038 std::cos(expectedRotationAngle), 1053 std::cos(expectedRotationAngle),
1039 0, 1054 0,
1040 0, 1055 0,
1041 to, 1056 to,
1042 ERROR_THRESHOLD); 1057 ERROR_THRESHOLD);
1043 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); 1058 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1044 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 1059 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1045 1060
1046 to = Transform(); 1061 to = Transform();
1047 to.PreconcatRotateAbout(Point3F(0, 0, 1), 90); 1062 to.RotateAbout(Vector3dF(0, 0, 1), 90);
1048 to.Blend(from, 1); 1063 to.Blend(from, 1);
1049 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD); 1064 EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD);
1050 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD); 1065 EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
1051 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD); 1066 EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
1052 EXPECT_ROW4_EQ(0, 0, 0, 1, to); 1067 EXPECT_ROW4_EQ(0, 0, 0, 1, to);
1053 } 1068 }
1054 1069
1055 TEST(XFormTest, VerifyBlendForCompositeTransform) 1070 TEST(XFormTest, VerifyBlendForCompositeTransform)
1056 { 1071 {
1057 // Verify that the.Blending was done with a decomposition in correct order 1072 // Verify that the.Blending was done with a decomposition in correct order
1058 // by blending a composite transform. Using matrix x vector notation 1073 // by blending a composite transform. Using matrix x vector notation
1059 // (Ax = b, where x is column vector), the ordering should be: 1074 // (Ax = b, where x is column vector), the ordering should be:
1060 // perspective * translation * rotation * skew * scale 1075 // perspective * translation * rotation * skew * scale
1061 // 1076 //
1062 // It is not as important (or meaningful) to check intermediate 1077 // It is not as important (or meaningful) to check intermediate
1063 // interpolations; order of operations will be tested well enough by the 1078 // interpolations; order of operations will be tested well enough by the
1064 // end cases that are easier to specify. 1079 // end cases that are easier to specify.
1065 1080
1066 Transform from; 1081 Transform from;
1067 Transform to; 1082 Transform to;
1068 1083
1069 Transform expectedEndOfAnimation; 1084 Transform expectedEndOfAnimation;
1070 expectedEndOfAnimation.PreconcatPerspectiveDepth(1); 1085 expectedEndOfAnimation.ApplyPerspectiveDepth(1);
1071 expectedEndOfAnimation.PreconcatTranslate3d(10, 20, 30); 1086 expectedEndOfAnimation.Translate3d(10, 20, 30);
1072 expectedEndOfAnimation.PreconcatRotateAbout(Point3F(0, 0, 1), 25); 1087 expectedEndOfAnimation.RotateAbout(Vector3dF(0, 0, 1), 25);
1073 expectedEndOfAnimation.PreconcatSkewY(45); 1088 expectedEndOfAnimation.SkewY(45);
1074 expectedEndOfAnimation.PreconcatScale3d(6, 7, 8); 1089 expectedEndOfAnimation.Scale3d(6, 7, 8);
1075 1090
1076 to = expectedEndOfAnimation; 1091 to = expectedEndOfAnimation;
1077 to.Blend(from, 0); 1092 to.Blend(from, 0);
1078 EXPECT_EQ(from, to); 1093 EXPECT_EQ(from, to);
1079 1094
1080 to = expectedEndOfAnimation; 1095 to = expectedEndOfAnimation;
1081 // We short circuit if blend is >= 1, so to check the numerics, we will 1096 // We short circuit if blend is >= 1, so to check the numerics, we will
1082 // check that we get close to what we expect when we're nearly done 1097 // check that we get close to what we expect when we're nearly done
1083 // interpolating. 1098 // interpolating.
1084 to.Blend(from, .99999); 1099 to.Blend(from, .99999);
1085 1100
1086 // Recomposing the matrix results in a normalized matrix, so to verify we 1101 // Recomposing the matrix results in a normalized matrix, so to verify we
1087 // need to normalize the expectedEndOfAnimation before comparing elements. 1102 // need to normalize the expectedEndOfAnimation before comparing elements.
1088 // Normalizing means dividing everything by expectedEndOfAnimation.m44(). 1103 // Normalizing means dividing everything by expectedEndOfAnimation.m44().
1089 Transform normalizedExpectedEndOfAnimation = expectedEndOfAnimation; 1104 Transform normalizedExpectedEndOfAnimation = expectedEndOfAnimation;
1090 Transform normalizationMatrix; 1105 Transform normalizationMatrix;
1091 normalizationMatrix.matrix().set( 1106 normalizationMatrix.matrix().set(
1092 0, 0, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); 1107 0, 0, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
1093 normalizationMatrix.matrix().set( 1108 normalizationMatrix.matrix().set(
1094 1, 1, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); 1109 1, 1, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
1095 normalizationMatrix.matrix().set( 1110 normalizationMatrix.matrix().set(
1096 2, 2, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); 1111 2, 2, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
1097 normalizationMatrix.matrix().set( 1112 normalizationMatrix.matrix().set(
1098 3, 3, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3))); 1113 3, 3, SkDoubleToMScalar(1 / expectedEndOfAnimation.matrix().get(3, 3)));
1099 normalizedExpectedEndOfAnimation.PreconcatTransform(normalizationMatrix); 1114 normalizedExpectedEndOfAnimation.PreconcatTransform(normalizationMatrix);
1100 1115
1101 EXPECT_TRUE(MatricesAreNearlyEqual(normalizedExpectedEndOfAnimation, to)); 1116 EXPECT_TRUE(MatricesAreNearlyEqual(normalizedExpectedEndOfAnimation, to));
1102 } 1117 }
1103 1118
1104 TEST(XFormTest, SetScaleZ)
1105 {
1106 Transform scaled;
1107 scaled.SetScaleZ(2);
1108 EXPECT_FLOAT_EQ(2, scaled.matrix().get(2, 2));
1109 }
1110
1111 TEST(XFormTest, SetTranslateZ)
1112 {
1113 Transform translated;
1114 translated.SetTranslateZ(2);
1115 EXPECT_FLOAT_EQ(2, translated.matrix().get(2, 3));
1116 }
1117
1118 TEST(XFormTest, DecomposedTransformCtor) 1119 TEST(XFormTest, DecomposedTransformCtor)
1119 { 1120 {
1120 DecomposedTransform decomp; 1121 DecomposedTransform decomp;
1121 for (int i = 0; i < 3; ++i) { 1122 for (int i = 0; i < 3; ++i) {
1122 EXPECT_EQ(0.0, decomp.translate[i]); 1123 EXPECT_EQ(0.0, decomp.translate[i]);
1123 EXPECT_EQ(1.0, decomp.scale[i]); 1124 EXPECT_EQ(1.0, decomp.scale[i]);
1124 EXPECT_EQ(0.0, decomp.skew[i]); 1125 EXPECT_EQ(0.0, decomp.skew[i]);
1125 EXPECT_EQ(0.0, decomp.quaternion[i]); 1126 EXPECT_EQ(0.0, decomp.quaternion[i]);
1126 EXPECT_EQ(0.0, decomp.perspective[i]); 1127 EXPECT_EQ(0.0, decomp.perspective[i]);
1127 } 1128 }
1128 EXPECT_EQ(1.0, decomp.quaternion[3]); 1129 EXPECT_EQ(1.0, decomp.quaternion[3]);
1129 EXPECT_EQ(1.0, decomp.perspective[3]); 1130 EXPECT_EQ(1.0, decomp.perspective[3]);
1130 Transform identity; 1131 Transform identity;
1131 Transform composed = ComposeTransform(decomp); 1132 Transform composed = ComposeTransform(decomp);
1132 EXPECT_TRUE(MatricesAreNearlyEqual(identity, composed)); 1133 EXPECT_TRUE(MatricesAreNearlyEqual(identity, composed));
1133 } 1134 }
1134 1135
1136 TEST(XFormTest, FactorTRS) {
1137 for (int degrees = 0; degrees < 180; ++degrees) {
1138 // build a transformation matrix.
1139 gfx::Transform transform;
1140 transform.Translate(degrees * 2, -degrees * 3);
1141 transform.Rotate(degrees);
1142 transform.Scale(degrees + 1, 2 * degrees + 1);
1143
1144 // factor the matrix
1145 DecomposedTransform decomp;
1146 bool success = DecomposeTransform(&decomp, transform);
1147 EXPECT_TRUE(success);
1148 EXPECT_FLOAT_EQ(decomp.translate[0], degrees * 2);
1149 EXPECT_FLOAT_EQ(decomp.translate[1], -degrees * 3);
1150 double rotation = std::acos(decomp.quaternion[3]) * 360.0 / M_PI;
1151 while (rotation < 0.0)
1152 rotation += 360.0;
1153 while (rotation > 360.0)
1154 rotation -= 360.0;
1155 EXPECT_FLOAT_EQ(rotation, degrees);
1156 EXPECT_FLOAT_EQ(decomp.scale[0], degrees + 1);
1157 EXPECT_FLOAT_EQ(decomp.scale[1], 2 * degrees + 1);
1158 }
1159 }
1160
1135 } // namespace 1161 } // namespace
1136 1162
1137 } // namespace gfx 1163 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/transform.cc ('k') | ui/gfx/transform_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698