Home | History | Annotate | Download | only in geometry
      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 
     12 namespace gfx {
     13 
     14 TEST(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 
     22 TEST(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 
     40 TEST(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 
     58 TEST(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 
    142 TEST(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 
    179 TEST(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 
    204 TEST(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 
    232 TEST(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