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/vector3d_f.h" 11 12namespace gfx { 13 14TEST(Vector3dTest, IsZero) { 15 gfx::Vector3dF float_zero(0, 0, 0); 16 gfx::Vector3dF float_nonzero(0.1f, -0.1f, 0.1f); 17 18 EXPECT_TRUE(float_zero.IsZero()); 19 EXPECT_FALSE(float_nonzero.IsZero()); 20} 21 22TEST(Vector3dTest, Add) { 23 gfx::Vector3dF f1(3.1f, 5.1f, 2.7f); 24 gfx::Vector3dF f2(4.3f, -1.3f, 8.1f); 25 26 const struct { 27 gfx::Vector3dF expected; 28 gfx::Vector3dF actual; 29 } float_tests[] = { 30 { gfx::Vector3dF(3.1F, 5.1F, 2.7f), f1 + gfx::Vector3dF() }, 31 { gfx::Vector3dF(3.1f + 4.3f, 5.1f - 1.3f, 2.7f + 8.1f), f1 + f2 }, 32 { gfx::Vector3dF(3.1f - 4.3f, 5.1f + 1.3f, 2.7f - 8.1f), f1 - f2 } 33 }; 34 35 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i) 36 EXPECT_EQ(float_tests[i].expected.ToString(), 37 float_tests[i].actual.ToString()); 38} 39 40TEST(Vector3dTest, Negative) { 41 const struct { 42 gfx::Vector3dF expected; 43 gfx::Vector3dF actual; 44 } float_tests[] = { 45 { gfx::Vector3dF(-0.0f, -0.0f, -0.0f), -gfx::Vector3dF(0, 0, 0) }, 46 { gfx::Vector3dF(-0.3f, -0.3f, -0.3f), -gfx::Vector3dF(0.3f, 0.3f, 0.3f) }, 47 { gfx::Vector3dF(0.3f, 0.3f, 0.3f), -gfx::Vector3dF(-0.3f, -0.3f, -0.3f) }, 48 { gfx::Vector3dF(-0.3f, 0.3f, -0.3f), -gfx::Vector3dF(0.3f, -0.3f, 0.3f) }, 49 { gfx::Vector3dF(0.3f, -0.3f, -0.3f), -gfx::Vector3dF(-0.3f, 0.3f, 0.3f) }, 50 { gfx::Vector3dF(-0.3f, -0.3f, 0.3f), -gfx::Vector3dF(0.3f, 0.3f, -0.3f) } 51 }; 52 53 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i) 54 EXPECT_EQ(float_tests[i].expected.ToString(), 55 float_tests[i].actual.ToString()); 56} 57 58TEST(Vector3dTest, Scale) { 59 float triple_values[][6] = { 60 { 4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f }, 61 { 4.5f, -1.2f, -1.8f, 3.3f, 5.6f, 4.2f }, 62 { 4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 4.2f }, 63 { 4.5f, -1.2f -1.8f, 3.3f, 5.6f, 4.2f }, 64 65 { 4.5f, 1.2f, 1.8f, 3.3f, -5.6f, -4.2f }, 66 { 4.5f, 1.2f, 1.8f, -3.3f, -5.6f, -4.2f }, 67 { 4.5f, 1.2f, -1.8f, 3.3f, -5.6f, -4.2f }, 68 { 4.5f, 1.2f, -1.8f, -3.3f, -5.6f, -4.2f }, 69 70 { -4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f }, 71 { -4.5f, 1.2f, 1.8f, 0, 5.6f, 4.2f }, 72 { -4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 4.2f }, 73 { -4.5f, 1.2f, -1.8f, 0, 5.6f, 4.2f }, 74 75 { -4.5f, 1.2f, 1.8f, 3.3f, 0, 4.2f }, 76 { 4.5f, 0, 1.8f, 3.3f, 5.6f, 4.2f }, 77 { -4.5f, 1.2f, -1.8f, 3.3f, 0, 4.2f }, 78 { 4.5f, 0, -1.8f, 3.3f, 5.6f, 4.2f }, 79 { -4.5f, 1.2f, 1.8f, 3.3f, 5.6f, 0 }, 80 { -4.5f, 1.2f, -1.8f, 3.3f, 5.6f, 0 }, 81 82 { 0, 1.2f, 0, 3.3f, 5.6f, 4.2f }, 83 { 0, 1.2f, 1.8f, 3.3f, 5.6f, 4.2f } 84 }; 85 86 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(triple_values); ++i) { 87 gfx::Vector3dF v(triple_values[i][0], 88 triple_values[i][1], 89 triple_values[i][2]); 90 v.Scale(triple_values[i][3], triple_values[i][4], triple_values[i][5]); 91 EXPECT_EQ(triple_values[i][0] * triple_values[i][3], v.x()); 92 EXPECT_EQ(triple_values[i][1] * triple_values[i][4], v.y()); 93 EXPECT_EQ(triple_values[i][2] * triple_values[i][5], v.z()); 94 95 Vector3dF v2 = ScaleVector3d( 96 gfx::Vector3dF(triple_values[i][0], 97 triple_values[i][1], 98 triple_values[i][2]), 99 triple_values[i][3], triple_values[i][4], triple_values[i][5]); 100 EXPECT_EQ(triple_values[i][0] * triple_values[i][3], v2.x()); 101 EXPECT_EQ(triple_values[i][1] * triple_values[i][4], v2.y()); 102 EXPECT_EQ(triple_values[i][2] * triple_values[i][5], v2.z()); 103 } 104 105 float single_values[][4] = { 106 { 4.5f, 1.2f, 1.8f, 3.3f }, 107 { 4.5f, -1.2f, 1.8f, 3.3f }, 108 { 4.5f, 1.2f, -1.8f, 3.3f }, 109 { 4.5f, -1.2f, -1.8f, 3.3f }, 110 { -4.5f, 1.2f, 3.3f }, 111 { -4.5f, 1.2f, 0 }, 112 { -4.5f, 1.2f, 1.8f, 3.3f }, 113 { -4.5f, 1.2f, 1.8f, 0 }, 114 { 4.5f, 0, 1.8f, 3.3f }, 115 { 0, 1.2f, 1.8f, 3.3f }, 116 { 4.5f, 0, 1.8f, 3.3f }, 117 { 0, 1.2f, 1.8f, 3.3f }, 118 { 4.5f, 1.2f, 0, 3.3f }, 119 { 4.5f, 1.2f, 0, 3.3f } 120 }; 121 122 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(single_values); ++i) { 123 gfx::Vector3dF v(single_values[i][0], 124 single_values[i][1], 125 single_values[i][2]); 126 v.Scale(single_values[i][3]); 127 EXPECT_EQ(single_values[i][0] * single_values[i][3], v.x()); 128 EXPECT_EQ(single_values[i][1] * single_values[i][3], v.y()); 129 EXPECT_EQ(single_values[i][2] * single_values[i][3], v.z()); 130 131 Vector3dF v2 = ScaleVector3d( 132 gfx::Vector3dF(single_values[i][0], 133 single_values[i][1], 134 single_values[i][2]), 135 single_values[i][3]); 136 EXPECT_EQ(single_values[i][0] * single_values[i][3], v2.x()); 137 EXPECT_EQ(single_values[i][1] * single_values[i][3], v2.y()); 138 EXPECT_EQ(single_values[i][2] * single_values[i][3], v2.z()); 139 } 140} 141 142TEST(Vector3dTest, Length) { 143 float float_values[][3] = { 144 { 0, 0, 0 }, 145 { 10.5f, 20.5f, 8.5f }, 146 { 20.5f, 10.5f, 8.5f }, 147 { 8.5f, 20.5f, 10.5f }, 148 { 10.5f, 8.5f, 20.5f }, 149 { -10.5f, -20.5f, -8.5f }, 150 { -20.5f, 10.5f, -8.5f }, 151 { -8.5f, -20.5f, -10.5f }, 152 { -10.5f, -8.5f, -20.5f }, 153 { 10.5f, -20.5f, 8.5f }, 154 { -10.5f, 20.5f, 8.5f }, 155 { 10.5f, -20.5f, -8.5f }, 156 { -10.5f, 20.5f, -8.5f }, 157 // A large vector that fails if the Length function doesn't use 158 // double precision internally. 159 { 1236278317862780234892374893213178027.12122348904204230f, 160 335890352589839028212313231225425134332.38123f, 161 27861786423846742743236423478236784678.236713617231f } 162 }; 163 164 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_values); ++i) { 165 double v0 = float_values[i][0]; 166 double v1 = float_values[i][1]; 167 double v2 = float_values[i][2]; 168 double length_squared = 169 static_cast<double>(v0) * v0 + 170 static_cast<double>(v1) * v1 + 171 static_cast<double>(v2) * v2; 172 double length = std::sqrt(length_squared); 173 gfx::Vector3dF vector(v0, v1, v2); 174 EXPECT_DOUBLE_EQ(length_squared, vector.LengthSquared()); 175 EXPECT_FLOAT_EQ(static_cast<float>(length), vector.Length()); 176 } 177} 178 179TEST(Vector3dTest, DotProduct) { 180 const struct { 181 float expected; 182 gfx::Vector3dF input1; 183 gfx::Vector3dF input2; 184 } tests[] = { 185 { 0, gfx::Vector3dF(1, 0, 0), gfx::Vector3dF(0, 1, 1) }, 186 { 0, gfx::Vector3dF(0, 1, 0), gfx::Vector3dF(1, 0, 1) }, 187 { 0, gfx::Vector3dF(0, 0, 1), gfx::Vector3dF(1, 1, 0) }, 188 189 { 3, gfx::Vector3dF(1, 1, 1), gfx::Vector3dF(1, 1, 1) }, 190 191 { 1.2f, gfx::Vector3dF(1.2f, -1.2f, 1.2f), gfx::Vector3dF(1, 1, 1) }, 192 { 1.2f, gfx::Vector3dF(1, 1, 1), gfx::Vector3dF(1.2f, -1.2f, 1.2f) }, 193 194 { 38.72f, 195 gfx::Vector3dF(1.1f, 2.2f, 3.3f), gfx::Vector3dF(4.4f, 5.5f, 6.6f) } 196 }; 197 198 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 199 float actual = gfx::DotProduct(tests[i].input1, tests[i].input2); 200 EXPECT_EQ(tests[i].expected, actual); 201 } 202} 203 204TEST(Vector3dTest, CrossProduct) { 205 const struct { 206 gfx::Vector3dF expected; 207 gfx::Vector3dF input1; 208 gfx::Vector3dF input2; 209 } tests[] = { 210 { Vector3dF(), Vector3dF(), Vector3dF(1, 1, 1) }, 211 { Vector3dF(), Vector3dF(1, 1, 1), Vector3dF() }, 212 { Vector3dF(), Vector3dF(1, 1, 1), Vector3dF(1, 1, 1) }, 213 { Vector3dF(), 214 Vector3dF(1.6f, 10.6f, -10.6f), 215 Vector3dF(1.6f, 10.6f, -10.6f) }, 216 217 { Vector3dF(1, -1, 0), Vector3dF(1, 1, 1), Vector3dF(0, 0, 1) }, 218 { Vector3dF(-1, 0, 1), Vector3dF(1, 1, 1), Vector3dF(0, 1, 0) }, 219 { Vector3dF(0, 1, -1), Vector3dF(1, 1, 1), Vector3dF(1, 0, 0) }, 220 221 { Vector3dF(-1, 1, 0), Vector3dF(0, 0, 1), Vector3dF(1, 1, 1) }, 222 { Vector3dF(1, 0, -1), Vector3dF(0, 1, 0), Vector3dF(1, 1, 1) }, 223 { Vector3dF(0, -1, 1), Vector3dF(1, 0, 0), Vector3dF(1, 1, 1) } 224 }; 225 226 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 227 Vector3dF actual = gfx::CrossProduct(tests[i].input1, tests[i].input2); 228 EXPECT_EQ(tests[i].expected.ToString(), actual.ToString()); 229 } 230} 231 232TEST(Vector3dFTest, ClampVector3dF) { 233 Vector3dF a; 234 235 a = Vector3dF(3.5f, 5.5f, 7.5f); 236 EXPECT_EQ(Vector3dF(3.5f, 5.5f, 7.5f).ToString(), a.ToString()); 237 a.SetToMax(Vector3dF(2, 4.5f, 6.5f)); 238 EXPECT_EQ(Vector3dF(3.5f, 5.5f, 7.5f).ToString(), a.ToString()); 239 a.SetToMax(Vector3dF(3.5f, 5.5f, 7.5f)); 240 EXPECT_EQ(Vector3dF(3.5f, 5.5f, 7.5f).ToString(), a.ToString()); 241 a.SetToMax(Vector3dF(4.5f, 2, 6.5f)); 242 EXPECT_EQ(Vector3dF(4.5f, 5.5f, 7.5f).ToString(), a.ToString()); 243 a.SetToMax(Vector3dF(3.5f, 6.5f, 6.5f)); 244 EXPECT_EQ(Vector3dF(4.5f, 6.5f, 7.5f).ToString(), a.ToString()); 245 a.SetToMax(Vector3dF(3.5f, 5.5f, 8.5f)); 246 EXPECT_EQ(Vector3dF(4.5f, 6.5f, 8.5f).ToString(), a.ToString()); 247 a.SetToMax(Vector3dF(8.5f, 10.5f, 12.5f)); 248 EXPECT_EQ(Vector3dF(8.5f, 10.5f, 12.5f).ToString(), a.ToString()); 249 250 a.SetToMin(Vector3dF(9.5f, 11.5f, 13.5f)); 251 EXPECT_EQ(Vector3dF(8.5f, 10.5f, 12.5f).ToString(), a.ToString()); 252 a.SetToMin(Vector3dF(8.5f, 10.5f, 12.5f)); 253 EXPECT_EQ(Vector3dF(8.5f, 10.5f, 12.5f).ToString(), a.ToString()); 254 a.SetToMin(Vector3dF(7.5f, 11.5f, 13.5f)); 255 EXPECT_EQ(Vector3dF(7.5f, 10.5f, 12.5f).ToString(), a.ToString()); 256 a.SetToMin(Vector3dF(9.5f, 9.5f, 13.5f)); 257 EXPECT_EQ(Vector3dF(7.5f, 9.5f, 12.5f).ToString(), a.ToString()); 258 a.SetToMin(Vector3dF(9.5f, 11.5f, 11.5f)); 259 EXPECT_EQ(Vector3dF(7.5f, 9.5f, 11.5f).ToString(), a.ToString()); 260 a.SetToMin(Vector3dF(3.5f, 5.5f, 7.5f)); 261 EXPECT_EQ(Vector3dF(3.5f, 5.5f, 7.5f).ToString(), a.ToString()); 262} 263 264} // namespace gfx 265