1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <cmath>
6#include <limits>
7
8#include "base/basictypes.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "ui/gfx/geometry/vector2d.h"
11#include "ui/gfx/geometry/vector2d_f.h"
12
13namespace gfx {
14
15TEST(Vector2dTest, ConversionToFloat) {
16  Vector2d i(3, 4);
17  Vector2dF f = i;
18  EXPECT_EQ(i, f);
19}
20
21TEST(Vector2dTest, IsZero) {
22  Vector2d int_zero(0, 0);
23  Vector2d int_nonzero(2, -2);
24  Vector2dF float_zero(0, 0);
25  Vector2dF float_nonzero(0.1f, -0.1f);
26
27  EXPECT_TRUE(int_zero.IsZero());
28  EXPECT_FALSE(int_nonzero.IsZero());
29  EXPECT_TRUE(float_zero.IsZero());
30  EXPECT_FALSE(float_nonzero.IsZero());
31}
32
33TEST(Vector2dTest, Add) {
34  Vector2d i1(3, 5);
35  Vector2d i2(4, -1);
36
37  const struct {
38    Vector2d expected;
39    Vector2d actual;
40  } int_tests[] = {
41    { Vector2d(3, 5), i1 + Vector2d() },
42    { Vector2d(3 + 4, 5 - 1), i1 + i2 },
43    { Vector2d(3 - 4, 5 + 1), i1 - i2 }
44  };
45
46  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(int_tests); ++i)
47    EXPECT_EQ(int_tests[i].expected.ToString(),
48              int_tests[i].actual.ToString());
49
50  Vector2dF f1(3.1f, 5.1f);
51  Vector2dF f2(4.3f, -1.3f);
52
53  const struct {
54    Vector2dF expected;
55    Vector2dF actual;
56  } float_tests[] = {
57    { Vector2dF(3.1F, 5.1F), f1 + Vector2d() },
58    { Vector2dF(3.1F, 5.1F), f1 + Vector2dF() },
59    { Vector2dF(3.1f + 4.3f, 5.1f - 1.3f), f1 + f2 },
60    { Vector2dF(3.1f - 4.3f, 5.1f + 1.3f), f1 - f2 }
61  };
62
63  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i)
64    EXPECT_EQ(float_tests[i].expected.ToString(),
65              float_tests[i].actual.ToString());
66}
67
68TEST(Vector2dTest, Negative) {
69  const struct {
70    Vector2d expected;
71    Vector2d actual;
72  } int_tests[] = {
73    { Vector2d(0, 0), -Vector2d(0, 0) },
74    { Vector2d(-3, -3), -Vector2d(3, 3) },
75    { Vector2d(3, 3), -Vector2d(-3, -3) },
76    { Vector2d(-3, 3), -Vector2d(3, -3) },
77    { Vector2d(3, -3), -Vector2d(-3, 3) }
78  };
79
80  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(int_tests); ++i)
81    EXPECT_EQ(int_tests[i].expected.ToString(),
82              int_tests[i].actual.ToString());
83
84  const struct {
85    Vector2dF expected;
86    Vector2dF actual;
87  } float_tests[] = {
88    { Vector2dF(0, 0), -Vector2d(0, 0) },
89    { Vector2dF(-0.3f, -0.3f), -Vector2dF(0.3f, 0.3f) },
90    { Vector2dF(0.3f, 0.3f), -Vector2dF(-0.3f, -0.3f) },
91    { Vector2dF(-0.3f, 0.3f), -Vector2dF(0.3f, -0.3f) },
92    { Vector2dF(0.3f, -0.3f), -Vector2dF(-0.3f, 0.3f) }
93  };
94
95  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i)
96    EXPECT_EQ(float_tests[i].expected.ToString(),
97              float_tests[i].actual.ToString());
98}
99
100TEST(Vector2dTest, Scale) {
101  float double_values[][4] = {
102    { 4.5f, 1.2f, 3.3f, 5.6f },
103    { 4.5f, -1.2f, 3.3f, 5.6f },
104    { 4.5f, 1.2f, 3.3f, -5.6f },
105    { 4.5f, 1.2f, -3.3f, -5.6f },
106    { -4.5f, 1.2f, 3.3f, 5.6f },
107    { -4.5f, 1.2f, 0, 5.6f },
108    { -4.5f, 1.2f, 3.3f, 0 },
109    { 4.5f, 0, 3.3f, 5.6f },
110    { 0, 1.2f, 3.3f, 5.6f }
111  };
112
113  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(double_values); ++i) {
114    Vector2dF v(double_values[i][0], double_values[i][1]);
115    v.Scale(double_values[i][2], double_values[i][3]);
116    EXPECT_EQ(v.x(), double_values[i][0] * double_values[i][2]);
117    EXPECT_EQ(v.y(), double_values[i][1] * double_values[i][3]);
118
119    Vector2dF v2 = ScaleVector2d(
120        gfx::Vector2dF(double_values[i][0], double_values[i][1]),
121        double_values[i][2], double_values[i][3]);
122    EXPECT_EQ(double_values[i][0] * double_values[i][2], v2.x());
123    EXPECT_EQ(double_values[i][1] * double_values[i][3], v2.y());
124  }
125
126  float single_values[][3] = {
127    { 4.5f, 1.2f, 3.3f },
128    { 4.5f, -1.2f, 3.3f },
129    { 4.5f, 1.2f, 3.3f },
130    { 4.5f, 1.2f, -3.3f },
131    { -4.5f, 1.2f, 3.3f },
132    { -4.5f, 1.2f, 0 },
133    { -4.5f, 1.2f, 3.3f },
134    { 4.5f, 0, 3.3f },
135    { 0, 1.2f, 3.3f }
136  };
137
138  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(single_values); ++i) {
139    Vector2dF v(single_values[i][0], single_values[i][1]);
140    v.Scale(single_values[i][2]);
141    EXPECT_EQ(v.x(), single_values[i][0] * single_values[i][2]);
142    EXPECT_EQ(v.y(), single_values[i][1] * single_values[i][2]);
143
144    Vector2dF v2 = ScaleVector2d(
145        gfx::Vector2dF(double_values[i][0], double_values[i][1]),
146        double_values[i][2]);
147    EXPECT_EQ(single_values[i][0] * single_values[i][2], v2.x());
148    EXPECT_EQ(single_values[i][1] * single_values[i][2], v2.y());
149  }
150}
151
152TEST(Vector2dTest, Length) {
153  int int_values[][2] = {
154    { 0, 0 },
155    { 10, 20 },
156    { 20, 10 },
157    { -10, -20 },
158    { -20, 10 },
159    { 10, -20 },
160  };
161
162  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(int_values); ++i) {
163    int v0 = int_values[i][0];
164    int v1 = int_values[i][1];
165    double length_squared =
166        static_cast<double>(v0) * v0 + static_cast<double>(v1) * v1;
167    double length = std::sqrt(length_squared);
168    Vector2d vector(v0, v1);
169    EXPECT_EQ(static_cast<float>(length_squared), vector.LengthSquared());
170    EXPECT_EQ(static_cast<float>(length), vector.Length());
171  }
172
173  float float_values[][2] = {
174    { 0, 0 },
175    { 10.5f, 20.5f },
176    { 20.5f, 10.5f },
177    { -10.5f, -20.5f },
178    { -20.5f, 10.5f },
179    { 10.5f, -20.5f },
180    // A large vector that fails if the Length function doesn't use
181    // double precision internally.
182    { 1236278317862780234892374893213178027.12122348904204230f,
183      335890352589839028212313231225425134332.38123f },
184  };
185
186  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_values); ++i) {
187    double v0 = float_values[i][0];
188    double v1 = float_values[i][1];
189    double length_squared =
190        static_cast<double>(v0) * v0 + static_cast<double>(v1) * v1;
191    double length = std::sqrt(length_squared);
192    Vector2dF vector(v0, v1);
193    EXPECT_DOUBLE_EQ(length_squared, vector.LengthSquared());
194    EXPECT_FLOAT_EQ(static_cast<float>(length), vector.Length());
195  }
196}
197
198TEST(Vector2dTest, ClampVector2d) {
199  Vector2d a;
200
201  a = Vector2d(3, 5);
202  EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString());
203  a.SetToMax(Vector2d(2, 4));
204  EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString());
205  a.SetToMax(Vector2d(3, 5));
206  EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString());
207  a.SetToMax(Vector2d(4, 2));
208  EXPECT_EQ(Vector2d(4, 5).ToString(), a.ToString());
209  a.SetToMax(Vector2d(8, 10));
210  EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString());
211
212  a.SetToMin(Vector2d(9, 11));
213  EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString());
214  a.SetToMin(Vector2d(8, 10));
215  EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString());
216  a.SetToMin(Vector2d(11, 9));
217  EXPECT_EQ(Vector2d(8, 9).ToString(), a.ToString());
218  a.SetToMin(Vector2d(7, 11));
219  EXPECT_EQ(Vector2d(7, 9).ToString(), a.ToString());
220  a.SetToMin(Vector2d(3, 5));
221  EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString());
222}
223
224TEST(Vector2dTest, ClampVector2dF) {
225  Vector2dF a;
226
227  a = Vector2dF(3.5f, 5.5f);
228  EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString());
229  a.SetToMax(Vector2dF(2.5f, 4.5f));
230  EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString());
231  a.SetToMax(Vector2dF(3.5f, 5.5f));
232  EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString());
233  a.SetToMax(Vector2dF(4.5f, 2.5f));
234  EXPECT_EQ(Vector2dF(4.5f, 5.5f).ToString(), a.ToString());
235  a.SetToMax(Vector2dF(8.5f, 10.5f));
236  EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString());
237
238  a.SetToMin(Vector2dF(9.5f, 11.5f));
239  EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString());
240  a.SetToMin(Vector2dF(8.5f, 10.5f));
241  EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString());
242  a.SetToMin(Vector2dF(11.5f, 9.5f));
243  EXPECT_EQ(Vector2dF(8.5f, 9.5f).ToString(), a.ToString());
244  a.SetToMin(Vector2dF(7.5f, 11.5f));
245  EXPECT_EQ(Vector2dF(7.5f, 9.5f).ToString(), a.ToString());
246  a.SetToMin(Vector2dF(3.5f, 5.5f));
247  EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString());
248}
249
250}  // namespace gfx
251