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/terrain/height_map.h>
00031 #include <towr/terrain/examples/height_map_examples.h>
00032
00033 #include <cmath>
00034
00035 namespace towr {
00036
00037 HeightMap::Ptr
00038 HeightMap::MakeTerrain (TerrainID type)
00039 {
00040 switch (type) {
00041 case FlatID: return std::make_shared<FlatGround>(); break;
00042 case BlockID: return std::make_shared<Block>(); break;
00043 case StairsID: return std::make_shared<Stairs>(); break;
00044 case GapID: return std::make_shared<Gap>(); break;
00045 case SlopeID: return std::make_shared<Slope>(); break;
00046 case ChimneyID: return std::make_shared<Chimney>(); break;
00047 case ChimneyLRID: return std::make_shared<ChimneyLR>(); break;
00048 default: assert(false); break;
00049 }
00050 }
00051
00052 double
00053 HeightMap::GetDerivativeOfHeightWrt (Dim2D dim, double x, double y) const
00054 {
00055 switch (dim) {
00056 case X: return GetHeightDerivWrtX(x,y);
00057 case Y: return GetHeightDerivWrtY(x,y);
00058 default: assert(false);
00059 }
00060 }
00061
00062 HeightMap::Vector3d
00063 HeightMap::GetNormalizedBasis (Direction basis, double x, double y) const
00064 {
00065 return GetBasis(basis, x, y).normalized();
00066 }
00067
00068 HeightMap::Vector3d
00069 HeightMap::GetBasis (Direction basis, double x, double y,
00070 const DimDerivs& deriv) const
00071 {
00072 switch (basis) {
00073 case Normal: return GetNormal(x,y, deriv);
00074 case Tangent1: return GetTangent1(x,y, deriv);
00075 case Tangent2: return GetTangent2(x,y, deriv);
00076 default: assert(false);
00077 }
00078 }
00079
00080 HeightMap::Vector3d
00081 HeightMap::GetDerivativeOfNormalizedBasisWrt (Direction basis, Dim2D dim,
00082 double x, double y) const
00083 {
00084
00085 Vector3d dv_wrt_dim = GetBasis(basis, x, y, {dim});
00086
00087
00088 Vector3d v = GetBasis(basis, x,y, {});
00089 Vector3d dn_norm_wrt_n = GetDerivativeOfNormalizedVectorWrtNonNormalizedIndex(v, dim);
00090 return dn_norm_wrt_n.cwiseProduct(dv_wrt_dim);
00091 }
00092
00093 HeightMap::Vector3d
00094 HeightMap::GetNormal(double x, double y, const DimDerivs& deriv) const
00095 {
00096 Vector3d n;
00097
00098 bool basis_requested = deriv.empty();
00099
00100 for (auto dim : {X_,Y_}) {
00101 if (basis_requested)
00102 n(dim) = -GetDerivativeOfHeightWrt(dim, x, y);
00103 else
00104 n(dim) = -GetSecondDerivativeOfHeightWrt(dim, deriv.front(), x, y);
00105 }
00106
00107 n(Z) = basis_requested? 1.0 : 0.0;
00108
00109 return n;
00110 }
00111
00112 HeightMap::Vector3d
00113 HeightMap::GetTangent1 (double x, double y, const DimDerivs& deriv) const
00114 {
00115 Vector3d tx;
00116
00117 bool basis_requested = deriv.empty();
00118
00119 tx(X) = basis_requested? 1.0 : 0.0;
00120 tx(Y) = 0.0;
00121 tx(Z) = basis_requested? GetDerivativeOfHeightWrt(X_, x, y)
00122 : GetSecondDerivativeOfHeightWrt(X_, deriv.front(), x, y);
00123
00124 return tx;
00125 }
00126
00127 HeightMap::Vector3d
00128 HeightMap::GetTangent2 (double x, double y, const DimDerivs& deriv) const
00129 {
00130 Vector3d ty;
00131
00132 bool basis_requested = deriv.empty();
00133
00134 ty(X) = 0.0;
00135 ty(Y) = basis_requested? 1.0 : 0.0;
00136 ty(Z) = basis_requested? GetDerivativeOfHeightWrt(Y_, x,y)
00137 : GetSecondDerivativeOfHeightWrt(Y_, deriv.front(), x, y);
00138 return ty;
00139 }
00140
00141 HeightMap::Vector3d
00142 HeightMap::GetDerivativeOfNormalizedVectorWrtNonNormalizedIndex (
00143 const Vector3d& v, int idx) const
00144 {
00145
00146
00147 return 1/v.squaredNorm()*(v.norm() * Vector3d::Unit(idx) - v(idx)*v.normalized());
00148 }
00149
00150 double
00151 HeightMap::GetSecondDerivativeOfHeightWrt (Dim2D dim1, Dim2D dim2,
00152 double x, double y) const
00153 {
00154 if (dim1 == X_) {
00155 if (dim2 == X_) return GetHeightDerivWrtXX(x,y);
00156 if (dim2 == Y_) return GetHeightDerivWrtXY(x,y);
00157 } else {
00158 if (dim2 == X_) return GetHeightDerivWrtYX(x,y);
00159 if (dim2 == Y_) return GetHeightDerivWrtYY(x,y);
00160 }
00161
00162 assert(false);
00163 }
00164
00165 }