1 // Copyright 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.
5 #ifndef CC_BASE_MATH_UTIL_H_
6 #define CC_BASE_MATH_UTIL_H_
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "cc/base/cc_export.h"
13 #include "ui/gfx/point3_f.h"
14 #include "ui/gfx/point_f.h"
15 #include "ui/gfx/size.h"
16 #include "ui/gfx/transform.h"
18 namespace base
{ class Value
; }
30 struct HomogeneousCoordinate
{
31 HomogeneousCoordinate(double new_x
, double new_y
, double new_z
, double new_w
)
32 : x(new_x
), y(new_y
), z(new_z
), w(new_w
) {}
34 bool ShouldBeClipped() const { return w
<= 0.0; }
36 gfx::PointF
CartesianPoint2d() const {
38 return gfx::PointF(x
, y
);
40 // For now, because this code is used privately only by MathUtil, it should
41 // never be called when w == 0, and we do not yet need to handle that case.
43 double inv_w
= 1.0 / w
;
44 return gfx::PointF(x
* inv_w
, y
* inv_w
);
47 gfx::Point3F
CartesianPoint3d() const {
49 return gfx::Point3F(x
, y
, z
);
51 // For now, because this code is used privately only by MathUtil, it should
52 // never be called when w == 0, and we do not yet need to handle that case.
54 double inv_w
= 1.0 / w
;
55 return gfx::Point3F(x
* inv_w
, y
* inv_w
, z
* inv_w
);
64 class CC_EXPORT MathUtil
{
66 static const double kPiDouble
;
67 static const float kPiFloat
;
69 static double Deg2Rad(double deg
) { return deg
* kPiDouble
/ 180.0; }
70 static double Rad2Deg(double rad
) { return rad
* 180.0 / kPiDouble
; }
72 static float Deg2Rad(float deg
) { return deg
* kPiFloat
/ 180.0f
; }
73 static float Rad2Deg(float rad
) { return rad
* 180.0f
/ kPiFloat
; }
75 static float Round(float f
) {
76 return (f
> 0.f
) ? std::floor(f
+ 0.5f
) : std::ceil(f
- 0.5f
);
78 static double Round(double d
) {
79 return (d
> 0.0) ? std::floor(d
+ 0.5) : std::ceil(d
- 0.5);
82 // Background: Existing transform code does not do the right thing in
83 // MapRect / MapQuad / ProjectQuad when there is a perspective projection that
84 // causes one of the transformed vertices to go to w < 0. In those cases, it
85 // is necessary to perform clipping in homogeneous coordinates, after applying
86 // the transform, before dividing-by-w to convert to cartesian coordinates.
88 // These functions return the axis-aligned rect that encloses the correctly
89 // clipped, transformed polygon.
90 static gfx::Rect
MapClippedRect(const gfx::Transform
& transform
,
92 static gfx::RectF
MapClippedRect(const gfx::Transform
& transform
,
93 const gfx::RectF
& rect
);
94 static gfx::RectF
ProjectClippedRect(const gfx::Transform
& transform
,
95 const gfx::RectF
& rect
);
97 // Returns an array of vertices that represent the clipped polygon. After
98 // returning, indexes from 0 to num_vertices_in_clipped_quad are valid in the
99 // clipped_quad array. Note that num_vertices_in_clipped_quad may be zero,
100 // which means the entire quad was clipped, and none of the vertices in the
102 static void MapClippedQuad(const gfx::Transform
& transform
,
103 const gfx::QuadF
& src_quad
,
104 gfx::PointF clipped_quad
[8],
105 int* num_vertices_in_clipped_quad
);
107 static gfx::RectF
ComputeEnclosingRectOfVertices(gfx::PointF vertices
[],
109 static gfx::RectF
ComputeEnclosingClippedRect(
110 const HomogeneousCoordinate
& h1
,
111 const HomogeneousCoordinate
& h2
,
112 const HomogeneousCoordinate
& h3
,
113 const HomogeneousCoordinate
& h4
);
115 // NOTE: These functions do not do correct clipping against w = 0 plane, but
116 // they correctly detect the clipped condition via the boolean clipped.
117 static gfx::QuadF
MapQuad(const gfx::Transform
& transform
,
118 const gfx::QuadF
& quad
,
120 static gfx::PointF
MapPoint(const gfx::Transform
& transform
,
123 static gfx::Point3F
MapPoint(const gfx::Transform
&,
126 static gfx::QuadF
ProjectQuad(const gfx::Transform
& transform
,
127 const gfx::QuadF
& quad
,
129 static gfx::PointF
ProjectPoint(const gfx::Transform
& transform
,
133 static gfx::Vector2dF
ComputeTransform2dScaleComponents(const gfx::Transform
&,
134 float fallbackValue
);
136 // Returns the smallest angle between the given two vectors in degrees.
137 // Neither vector is assumed to be normalized.
138 static float SmallestAngleBetweenVectors(gfx::Vector2dF v1
,
141 // Projects the |source| vector onto |destination|. Neither vector is assumed
143 static gfx::Vector2dF
ProjectVector(gfx::Vector2dF source
,
144 gfx::Vector2dF destination
);
146 // Conversion to value.
147 static scoped_ptr
<base::Value
> AsValue(gfx::Size s
);
148 static scoped_ptr
<base::Value
> AsValue(gfx::PointF q
);
149 static scoped_ptr
<base::Value
> AsValue(gfx::QuadF q
);
151 // Returns a base::Value representation of the floating point value.
152 // If the value is inf, returns max double/float representation.
153 static scoped_ptr
<base::Value
> AsValueSafely(double value
);
154 static scoped_ptr
<base::Value
> AsValueSafely(float value
);
159 #endif // CC_BASE_MATH_UTIL_H_