00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <towr/height_map.h>
00031
00032 #include <cmath>
00033
00034 namespace towr {
00035
00036 double
00037 HeightMap::GetDerivativeOfHeightWrt (Dim2D dim, double x, double y) const
00038 {
00039 switch (dim) {
00040 case X: return GetHeightDerivWrtX(x,y);
00041 case Y: return GetHeightDerivWrtY(x,y);
00042 default: assert(false);
00043 }
00044 }
00045
00046 HeightMap::Vector3d
00047 HeightMap::GetNormalizedBasis (Direction basis, double x, double y) const
00048 {
00049 return GetBasis(basis, x, y).normalized();
00050 }
00051
00052 HeightMap::Vector3d
00053 HeightMap::GetBasis (Direction basis, double x, double y,
00054 const DimDerivs& deriv) const
00055 {
00056 switch (basis) {
00057 case Normal: return GetNormal(x,y, deriv);
00058 case Tangent1: return GetTangent1(x,y, deriv);
00059 case Tangent2: return GetTangent2(x,y, deriv);
00060 default: assert(false);
00061 }
00062 }
00063
00064 HeightMap::Vector3d
00065 HeightMap::GetDerivativeOfNormalizedBasisWrt (Direction basis, Dim2D dim,
00066 double x, double y) const
00067 {
00068
00069 Vector3d dv_wrt_dim = GetBasis(basis, x, y, {dim});
00070
00071
00072 Vector3d v = GetBasis(basis, x,y, {});
00073 Vector3d dn_norm_wrt_n = GetDerivativeOfNormalizedVectorWrtNonNormalizedIndex(v, dim);
00074 return dn_norm_wrt_n.cwiseProduct(dv_wrt_dim);
00075 }
00076
00077 HeightMap::Vector3d
00078 HeightMap::GetNormal(double x, double y, const DimDerivs& deriv) const
00079 {
00080 Vector3d n;
00081
00082 bool basis_requested = deriv.empty();
00083
00084 for (auto dim : {X_,Y_}) {
00085 if (basis_requested)
00086 n(dim) = -GetDerivativeOfHeightWrt(dim, x, y);
00087 else
00088 n(dim) = -GetSecondDerivativeOfHeightWrt(dim, deriv.front(), x, y);
00089 }
00090
00091 n(Z) = basis_requested? 1.0 : 0.0;
00092
00093 return n;
00094 }
00095
00096 HeightMap::Vector3d
00097 HeightMap::GetTangent1 (double x, double y, const DimDerivs& deriv) const
00098 {
00099 Vector3d tx;
00100
00101 bool basis_requested = deriv.empty();
00102
00103 tx(X) = basis_requested? 1.0 : 0.0;
00104 tx(Y) = 0.0;
00105 tx(Z) = basis_requested? GetDerivativeOfHeightWrt(X_, x, y)
00106 : GetSecondDerivativeOfHeightWrt(X_, deriv.front(), x, y);
00107
00108 return tx;
00109 }
00110
00111 HeightMap::Vector3d
00112 HeightMap::GetTangent2 (double x, double y, const DimDerivs& deriv) const
00113 {
00114 Vector3d ty;
00115
00116 bool basis_requested = deriv.empty();
00117
00118 ty(X) = 0.0;
00119 ty(Y) = basis_requested? 1.0 : 0.0;
00120 ty(Z) = basis_requested? GetDerivativeOfHeightWrt(Y_, x,y)
00121 : GetSecondDerivativeOfHeightWrt(Y_, deriv.front(), x, y);
00122 return ty;
00123 }
00124
00125 HeightMap::Vector3d
00126 HeightMap::GetDerivativeOfNormalizedVectorWrtNonNormalizedIndex (
00127 const Vector3d& v, int idx) const
00128 {
00129
00130
00131 return 1/v.squaredNorm()*(v.norm() * Vector3d::Unit(idx) - v(idx)*v.normalized());
00132 }
00133
00134 double
00135 HeightMap::GetSecondDerivativeOfHeightWrt (Dim2D dim1, Dim2D dim2,
00136 double x, double y) const
00137 {
00138 if (dim1 == X_) {
00139 if (dim2 == X_) return GetHeightDerivWrtXX(x,y);
00140 if (dim2 == Y_) return GetHeightDerivWrtXY(x,y);
00141 } else {
00142 if (dim2 == X_) return GetHeightDerivWrtYX(x,y);
00143 if (dim2 == Y_) return GetHeightDerivWrtYY(x,y);
00144 }
00145
00146 assert(false);
00147 }
00148
00149 }