xref: /aosp_15_r20/external/skia/tests/Point3Test.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker // Unit tests for src/core/SkPoint3.cpp and its header
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint3.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker #include <array>
16*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
17*c8dee2aaSAndroid Build Coastguard Worker 
test_eq_ops(skiatest::Reporter * reporter)18*c8dee2aaSAndroid Build Coastguard Worker static void test_eq_ops(skiatest::Reporter* reporter) {
19*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 p0 = SkPoint3::Make(0, 0, 0);
20*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 p1 = SkPoint3::Make(1, 1, 1);
21*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 p2 = SkPoint3::Make(1, 1, 1);
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, p0 != p1);
24*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, p1 == p2);
25*c8dee2aaSAndroid Build Coastguard Worker }
26*c8dee2aaSAndroid Build Coastguard Worker 
test_ops(skiatest::Reporter * reporter)27*c8dee2aaSAndroid Build Coastguard Worker static void test_ops(skiatest::Reporter* reporter) {
28*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 v = SkPoint3::Make(1, 1, 1);
29*c8dee2aaSAndroid Build Coastguard Worker     v.normalize();
30*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(v.length(), SK_Scalar1));
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker     // scale
33*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 p = v.makeScale(3.0f);
34*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.length(), 3.0f));
35*c8dee2aaSAndroid Build Coastguard Worker 
36*c8dee2aaSAndroid Build Coastguard Worker     p.scale(1.0f/3.0f);
37*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.length(), SK_Scalar1));
38*c8dee2aaSAndroid Build Coastguard Worker 
39*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 p1 = SkPoint3::Make(20.0f, 2.0f, 10.0f);
40*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 p2 = -p1;
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker     // -
43*c8dee2aaSAndroid Build Coastguard Worker     p = p1 - p1;
44*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.x(), 0.0f));
45*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.y(), 0.0f));
46*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.z(), 0.0f));
47*c8dee2aaSAndroid Build Coastguard Worker 
48*c8dee2aaSAndroid Build Coastguard Worker     // +
49*c8dee2aaSAndroid Build Coastguard Worker     p = p1 + p2;
50*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.x(), 0.0f));
51*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.y(), 0.0f));
52*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.z(), 0.0f));
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker 
test_dot(skiatest::Reporter * reporter)55*c8dee2aaSAndroid Build Coastguard Worker static void test_dot(skiatest::Reporter* reporter) {
56*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 xAxis = SkPoint3::Make(1.0f, 0.0f, 0.0f);
57*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 yAxis = SkPoint3::Make(0.0f, 1.0f, 0.0f);
58*c8dee2aaSAndroid Build Coastguard Worker     const SkPoint3 zAxis = SkPoint3::Make(0.0f, 0.0f, 1.0f);
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker     SkScalar dot = xAxis.dot(yAxis);
61*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, 0.0f));
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker     dot = yAxis.dot(zAxis);
64*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, 0.0f));
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     dot = zAxis.dot(xAxis);
67*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, 0.0f));
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 v = SkPoint3::Make(13.0f, 2.0f, 7.0f);
70*c8dee2aaSAndroid Build Coastguard Worker     v.normalize();
71*c8dee2aaSAndroid Build Coastguard Worker 
72*c8dee2aaSAndroid Build Coastguard Worker     dot = v.dot(v);
73*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, 1.0f));
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     v = SkPoint3::Make(SK_ScalarRoot2Over2, SK_ScalarRoot2Over2, 0.0f);
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker     dot = xAxis.dot(v);
78*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, SK_ScalarRoot2Over2));
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     dot = yAxis.dot(v);
81*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dot, SK_ScalarRoot2Over2));
82*c8dee2aaSAndroid Build Coastguard Worker }
83*c8dee2aaSAndroid Build Coastguard Worker 
test_length(skiatest::Reporter * reporter,SkScalar x,SkScalar y,SkScalar z,SkScalar expectedLen)84*c8dee2aaSAndroid Build Coastguard Worker static void test_length(skiatest::Reporter* reporter,
85*c8dee2aaSAndroid Build Coastguard Worker                         SkScalar x, SkScalar y, SkScalar z, SkScalar expectedLen) {
86*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 point = SkPoint3::Make(x, y, z);
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker     SkScalar s1 = point.length();
89*c8dee2aaSAndroid Build Coastguard Worker     SkScalar s2 = SkPoint3::Length(x, y, z);
90*c8dee2aaSAndroid Build Coastguard Worker 
91*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(s1, s2));
92*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(s1, expectedLen));
93*c8dee2aaSAndroid Build Coastguard Worker }
94*c8dee2aaSAndroid Build Coastguard Worker 
test_normalize(skiatest::Reporter * reporter,SkScalar x,SkScalar y,SkScalar z,SkScalar expectedLen)95*c8dee2aaSAndroid Build Coastguard Worker static void test_normalize(skiatest::Reporter* reporter,
96*c8dee2aaSAndroid Build Coastguard Worker                            SkScalar x, SkScalar y, SkScalar z, SkScalar expectedLen) {
97*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 point = SkPoint3::Make(x, y, z);
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker     bool result = point.normalize();
100*c8dee2aaSAndroid Build Coastguard Worker     SkScalar newLength = point.length();
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     if (0 == expectedLen) {
103*c8dee2aaSAndroid Build Coastguard Worker         const SkPoint3 empty = SkPoint3::Make(0.0f, 0.0f, 0.0f);
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(newLength, 0));
106*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !result);
107*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, point == empty);
108*c8dee2aaSAndroid Build Coastguard Worker     } else {
109*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, SkScalarNearlyEqual(newLength, SK_Scalar1));
110*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, result);
111*c8dee2aaSAndroid Build Coastguard Worker     }
112*c8dee2aaSAndroid Build Coastguard Worker     SkRandom random;
113*c8dee2aaSAndroid Build Coastguard Worker     random.setSeed(1234);
114*c8dee2aaSAndroid Build Coastguard Worker     SkPoint3 pt3;
115*c8dee2aaSAndroid Build Coastguard Worker     int testCount = 100000;
116*c8dee2aaSAndroid Build Coastguard Worker     for (int index = 0; index < testCount; ++index) {
117*c8dee2aaSAndroid Build Coastguard Worker         SkScalar testVal;
118*c8dee2aaSAndroid Build Coastguard Worker         do {
119*c8dee2aaSAndroid Build Coastguard Worker             testVal = random.nextRangeF(0, 2);
120*c8dee2aaSAndroid Build Coastguard Worker         } while (!testVal);
121*c8dee2aaSAndroid Build Coastguard Worker         pt3.set(testVal, 0, 0);
122*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, !pt3.normalize() || 1 == pt3.fX);
123*c8dee2aaSAndroid Build Coastguard Worker     }
124*c8dee2aaSAndroid Build Coastguard Worker }
125*c8dee2aaSAndroid Build Coastguard Worker 
DEF_TEST(Point3,reporter)126*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Point3, reporter) {
127*c8dee2aaSAndroid Build Coastguard Worker     test_eq_ops(reporter);
128*c8dee2aaSAndroid Build Coastguard Worker     test_ops(reporter);
129*c8dee2aaSAndroid Build Coastguard Worker     test_dot(reporter);
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker     static const struct {
132*c8dee2aaSAndroid Build Coastguard Worker         SkScalar fX;
133*c8dee2aaSAndroid Build Coastguard Worker         SkScalar fY;
134*c8dee2aaSAndroid Build Coastguard Worker         SkScalar fZ;
135*c8dee2aaSAndroid Build Coastguard Worker         SkScalar fLength;
136*c8dee2aaSAndroid Build Coastguard Worker     } gRec[] = {
137*c8dee2aaSAndroid Build Coastguard Worker         { 0.0f, 0.0f, 0.0f, 0.0f },
138*c8dee2aaSAndroid Build Coastguard Worker         { 0.3f, 0.4f, 0.5f, SK_ScalarRoot2Over2 },
139*c8dee2aaSAndroid Build Coastguard Worker         { 1.0e-37f, 1.0e-37f, 1.0e-37f, 0.0f },  // underflows
140*c8dee2aaSAndroid Build Coastguard Worker         { 3.4e38f, 0.0f, 0.0f, 3.4e38f }         // overflows
141*c8dee2aaSAndroid Build Coastguard Worker     };
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(gRec); ++i) {
144*c8dee2aaSAndroid Build Coastguard Worker         test_length(reporter, gRec[i].fX, gRec[i].fY, gRec[i].fZ, gRec[i].fLength);
145*c8dee2aaSAndroid Build Coastguard Worker         test_normalize(reporter, gRec[i].fX, gRec[i].fY, gRec[i].fZ, gRec[i].fLength);
146*c8dee2aaSAndroid Build Coastguard Worker     }
147*c8dee2aaSAndroid Build Coastguard Worker }
148