static Matrix4T<T> rotation(float degrees, const Vector3T<T> &inaxis) { Matrix4T<T> m; Vector3T<T> axis = inaxis; axis.normalize(); float c = cos((float)degToRad(degrees)); float s = sin((float)degToRad(degrees)); m.x.x = (axis.x * axis.x) * (1.0f - c) + c; m.y.x = (axis.y * axis.x) * (1.0f - c) + (axis.z * s); m.z.x = (axis.z * axis.x) * (1.0f - c) - (axis.y * s); m.x.y = (axis.x * axis.y) * (1.0f - c) - (axis.z * s); m.y.y = (axis.y * axis.y) * (1.0f - c) + c; m.z.y = (axis.z * axis.y) * (1.0f - c) + (axis.x * s); m.x.z = (axis.x * axis.z) * (1.0f - c) + (axis.y * s); m.y.z = (axis.y * axis.z) * (1.0f - c) - (axis.x * s); m.z.z = (axis.z * axis.z) * (1.0f - c) + c; return m; }
static Matrix4T<T> buildViewMatrix(const Vector3T<T> &from, const Vector3T<T> &lookingAt, const Vector3T<T> &up /*= Vector3(1,0,0)*/) { Matrix4T<T> r; r.SetPositionVector(Vector3T<T>(-from.x,-from.y,-from.z)); Matrix4T<T> m; Vector3T<T> f = (lookingAt - from); f.normalize(); Vector3T<T> s = Vector3T<T>::Cross(f,up); Vector3T<T> u = Vector3T<T>::Cross(s,f); m.x.x = s.x; m.x.y = s.y; m.x.z = s.z; m.y.x = u.x; m.y.y = u.y; m.y.z = u.z; m.z.x = -f.x; m.z.x = -f.y; m.z.z = -f.z; return m * r; }
/// sets row with vector components void Row(unsigned int uiRow, const Vector3T<T>& vRow) throw() { ATLASSERT(uiRow < 4); m_d[0][uiRow] = vRow.X(); m_d[1][uiRow] = vRow.Y(); m_d[2][uiRow] = vRow.Z(); }
/// sets column with vector components void Column(unsigned int uiColumn, const Vector3T<T>& vColumn) throw() { ATLASSERT(uiColumn < 4); m_d[uiColumn][0] = vColumn.X(); m_d[uiColumn][1] = vColumn.Y(); m_d[uiColumn][2] = vColumn.Z(); }
/// multiply operator Vector3T<T> operator*(const Vector3T<T>& v) const throw() { return Vector3T<T>( m_d[0][0] * v.X() + m_d[1][0] * v.Y() + m_d[2][0] * v.Z() + m_d[3][0], m_d[0][1] * v.X() + m_d[1][1] * v.Y() + m_d[2][1] * v.Z() + m_d[3][1], m_d[0][2] * v.X() + m_d[1][2] * v.Y() + m_d[2][2] * v.Z() + m_d[3][2] ); }
Vector3T normalized() const { Vector3T v = *this; v.normalize(); return v; }
int MeshFreeSupport3DT::Intersect(const double* x0, const double* x1, const double* x2, const double *vA, const double* vB) const { /* facet centroid */ Vector3T<double> xc; xc.Average(x0, x1, x2); /* "expand" facet to insure overlap */ // const double eps = 0.01; const double eps = 0.02; double eps1 = 1.0 + eps; Vector3T<double> v0, v1, v2; v0.Combine(eps1, x0, -eps, xc); v1.Combine(eps1, x1, -eps, xc); v2.Combine(eps1, x2, -eps, xc); /* workspace vectors */ Vector3T<double> v01, v12, vAB, N; /* edge vectors */ v01.Diff(v1, v0); v12.Diff(v2, v1); /* facet normal (direction) = v01 x v12 */ N.Cross(v01, v12); /* connecting vector */ vAB.Diff(vB, vA); /* intersection distance */ double den = Vector3T<double>::Dot(N, vAB); if (fabs(den) < kSmall) return 0; double s = (Vector3T<double>::Dot(N,v0) - Vector3T<double>::Dot(N,vA))/den; /* AB doesn't cross facet plane */ if (s < 0.0 || s > 1.0) return 0; else { Vector3T<double> vP, Ni, viP; vP.Combine(1.0, vA, s, vAB); /* edge 1 */ viP.Diff(vP, v0); Ni.Cross(v01, viP); if (Vector3T<double>::Dot(N, Ni) < 0.0) return 0; else { /* edge 2 */ viP.Diff(vP, v1); Ni.Cross(v12, viP); if (Vector3T<double>::Dot(N, Ni) < 0.0) return 0; else { Vector3T<double> v20; v20.Diff(v0, v2); /* edge 3 */ viP.Diff(vP, v2); Ni.Cross(v20, viP); if (Vector3T<double>::Dot(N, Ni) < 0.0) return 0; else return 1; } } } }
/// builds a rotation matrix from axis and angle static Matrix4T<T> Rotate(Vector3T<T> vAxis, T dAngleRot) { vAxis.Normalize(); T cs = std::cos(-dAngleRot); T sn = std::sin(-dAngleRot); T t = T(1.0) - cs; Matrix4T<T> matRotate; matRotate.Row(0, Vector3T<T>(t * vAxis.X() * vAxis.X() + cs, t * vAxis.X() * vAxis.Y() - sn * vAxis.Z(), t * vAxis.X() * vAxis.Z() + sn * vAxis.Y())); matRotate.Row(1, Vector3T<T>(t * vAxis.X() * vAxis.Y() + sn * vAxis.Z(), t * vAxis.Y() * vAxis.Y() + cs, t * vAxis.Y() * vAxis.Z() - sn * vAxis.X())); matRotate.Row(2, Vector3T<T>(t * vAxis.X() * vAxis.Z() - sn * vAxis.Y(), t * vAxis.Y() * vAxis.Z() + sn * vAxis.X(), t * vAxis.Z() * vAxis.Z() + cs)); matRotate[3][3] = 1.0; return matRotate; }
int main() { std::ofstream fout; fout.open("out.txt"); try { App app; app.SetLoggingFile("error.log"); app.LoadKernel("data/meta.tm"); app.SetReferenceFrame(Frame::ECLIPJ2000); // Set reference frame to ECLIPJ200, default is J2000 app.SetDefaultUnits(App::UT_DEFAULT); // Same as UT_METRIC, except Length is measured in km. This is set by default //app.SetDefaultUnits(App::UT_METRIC); // Default units are meters, meters per second and kilograms //app.SetDefaultUnits(App::UT_IMPERIAL); // Default units are miles, miles per hour and pounds //app.LoadSolarSystem(); // Loads Solar System. Optional parameter controls whether to load only planets and Sun or to load entire Solar System //app.LoadAllAvailableObjects(); // Loads all objects which were introduced in loaded kernels //app.LoadMoons(SpaceObject("Earth")); // Creates SpaceObjects instance and uses it to specify parent body //app.LoadMoons("Jupiter"); // Loads moons of Jupiter, internally the same as LoadMoons(SpaceObject("Jupiter")) //if(app.CheckObjectExists("Pluto")) // app.LoadMoons(app.RetrieveObject("Pluto")); // Same as LoadMoons(SpaceObject("Pluto")), except this doesn't construct new SpaceObject instance, instead it uses reference to already loaded SpaceObject instance app.AddObject(SpaceBody("europa")); app.AddObject(SpaceBody("MOON")); app.AddObject(SpaceBody("Io")); std::vector<SpaceObject*> barycenters = app.GetLoadedBarycenters(); std::vector<SpaceObject*> planets = app.GetLoadedPlanets(); std::vector<SpaceObject*> moons = app.GetLoadedMoons(); std::vector<SpaceObject*> jupiterMoons = app.GetLoadedMoonsOf(SpaceObject("Jupiter")); std::vector<SpaceObject*> marsMoons = app.GetLoadedMoonsOf(SpaceObject("mars")); app.LoadSolarSystem(true); std::vector<KernelData> kernels = CSpiceUtil::GetLoadedKernels(); fout << "Loaded kernels:" << std::endl; for(size_t i = 0; i < kernels.size(); i++) { KernelData kData = kernels[i]; fout << "\t" << kData.filename << " (" << kData.type << ")" << std::endl; } fout << std::endl; size_t objectsCount = app.GetObjectsLength(); for(size_t i = 0; i < objectsCount; i++) { const SpaceObject& obj = app.GetObjectByIndex(i); fout << obj.GetName() << " summary:" << std::endl; try { const SpaceBody& body = dynamic_cast<const SpaceBody&>(obj); fout << "Bulk parameters:" << std::endl; if(body.HasParameter(SpaceBody::BP_MASS)) fout << "\tMass: " << body.GetMass().ValueIn(app.MassUnit()) << " " << app.MassUnit().str() << std::endl; if(body.HasParameter(SpaceBody::BP_GM)) fout << "\tGM: " << body.GetGM().ValueIn(app.GMUnit()) << " " << app.GMUnit().str() << std::endl; if(body.HasParameter(SpaceBody::BP_ACC)) fout << "\tg: " << body.GetSurfaceAcceleration().ValueIn(app.AccelerationUnit()) << " " << app.AccelerationUnit().str() << std::endl; if(body.HasParameter(SpaceBody::BP_RADIUS)) { Length radius = body.GetRadius(); std::array<Length, 3> radii = body.GetRadii(); fout << "\tRadius: " << radius.ValueIn(app.LengthUnit()) << " (" << radii[0].ValueIn(app.LengthUnit()) << ", " << radii[1].ValueIn(app.LengthUnit()) << ", " << radii[2].ValueIn(app.LengthUnit()) << ") " << app.LengthUnit().str() << std::endl; } fout << std::endl; } catch(const std::bad_cast&) { } Date t("Aug 17 2000 15:51:01 UTC-5"); t += Time(1.0, Units::Common::days); Window spkCoverage = obj.GetCoverage(); std::vector<Interval> spkIntervals = spkCoverage.GetIntervals(); fout << "SPK state:" << std::endl; fout << "\tCoverage:" << std::endl; if(spkIntervals.size() == 0) { fout << "\t\tObject does not contain any state data" << std::endl; } for(size_t i = 0; i < spkIntervals.size(); i++) { Interval interval = spkIntervals[i]; Date begin(interval.GetLeft()); Date end(interval.GetRight()); fout << "\t\t" << begin.AsString() << " - " << end.AsString() << std::endl; } fout << std::endl; fout << "\t" << t.AsString() << " relative to " << app.GetReferenceFrame().GetName() << ":" << std::endl; if(spkCoverage.IsIncluded(t.AsDouble())) { Vector3T<Length> pos = obj.GetPosition(t, app.GetReferenceFrame()); Vector3T<Velocity> vel = obj.GetVelocity(t, app.GetReferenceFrame()); fout << "\t\tPos: " << pos.Length().ValueIn(app.LengthUnit()) << " (" << pos.x.ValueIn(app.LengthUnit()) << ", " << pos.y.ValueIn(app.LengthUnit()) << ", " << pos.z.ValueIn(app.LengthUnit()) << ") " << app.LengthUnit().str() << std::endl; fout << "\t\tVel: " << vel.Length().ValueIn(app.VelocityUnit()) << " (" << vel.x.ValueIn(app.VelocityUnit()) << ", " << vel.y.ValueIn(app.VelocityUnit()) << ", " << vel.z.ValueIn(app.VelocityUnit()) << ") " << app.VelocityUnit().str() << std::endl; } else { fout << "\t\tNo state data on this epoch" << std::endl; } fout << std::endl; try { const SpaceBody& body = dynamic_cast<const SpaceBody&>(obj); fout << "PCK orientation:" << std::endl; if(body.HasDefaultFrame()) { Frame bodyFrame = body.GetDefaultFrame(); fout << "(using frame " << bodyFrame.GetName() << ")" << std::endl; if(bodyFrame.HasAvailableData()) { bool dataAvailableAtT = true; fout << "\tCoverage:" << std::endl; if(bodyFrame.HasLimitedCoverage()) { Window pckCoverage = bodyFrame.GetCoverage(); std::vector<Interval> pckIntervals = pckCoverage.GetIntervals(); dataAvailableAtT = pckCoverage.IsIncluded(t.AsDouble()); if(pckIntervals.size() == 0) { fout << "\t\tObject does not contain any orientation data" << std::endl; } for(size_t i = 0; i < pckIntervals.size(); i++) { Interval interval = pckIntervals[i]; Date begin(interval.GetLeft()); Date end(interval.GetRight()); fout << "\t\t" << begin.AsString() << " - " << end.AsString() << std::endl; } fout << std::endl; } else { fout << "\t\tUnlimited" << std::endl; } fout << "\t" << t.AsString() << app.GetReferenceFrame().GetName() << ":" << std::endl; if(dataAvailableAtT) { Vector3 axisX = bodyFrame.AxisX(t, app.GetReferenceFrame()); Vector3 axisY = bodyFrame.AxisY(t, app.GetReferenceFrame()); Vector3 axisZ = bodyFrame.AxisZ(t, app.GetReferenceFrame()); fout << "\t\tX axis: (" << axisX.x << ", " << axisX.y << ", " << axisX.z << ")" << std::endl; fout << "\t\tY axis: (" << axisY.x << ", " << axisY.y << ", " << axisY.z << ")" << std::endl; fout << "\t\tZ axis: (" << axisZ.x << ", " << axisZ.y << ", " << axisZ.z << ")" << std::endl; const Matrix4x4& matrix = bodyFrame.GetTransformationMatrix(t, app.GetReferenceFrame()); fout << "\t\tTransformation matrix:" << std::endl; for(int row = 0; row < 4; row++) { fout << "\t\t\t"; for(int col = 0; col < 4; col++) { fout << std::fixed << std::setw(11) << matrix.Get(row, col) << std::defaultfloat << " "; } fout << std::endl; } } else { fout << "\t\tNo orientation data available on this epoch" << std::endl; } } else { fout << "\tFrame does not contain any orientation data" << std::endl; } } else { fout << "\tObject does not contain any orientation data" << std::endl; } } catch(const std::bad_cast&) { } fout << "===============================================================================" << std::endl; fout << std::endl; } std::cout << "All is fine. See out.txt for results" << std::endl; } catch(const std::exception& ex) { std::cout << std::endl; std::cout << "Error encountered:" << std::endl; std::cout << ex.what() << std::endl; std::cout << "See details in the error log file" << std::endl; } std::getchar(); return 0; }
inline Vector3T<T> operator/(const Vector3T<T>& vec, const T d) { return Vector3T<T>(vec.X()/d, vec.Y()/d, vec.Z()/d); }
inline Vector3T<T> operator-(const Vector3T<T>& v1, const Vector3T<T>& v2) throw() { return Vector3T<T>(v1.X() - v2.X(), v1.Y() - v2.Y(), v1.Z() - v2.Z()); }
inline Vector3T<T> operator-(const Vector3T<T>& vec) throw() { return Vector3T<T>(-vec.X(), -vec.Y(), -vec.Z()); };
/// calculates outer (cross) product Vector3T Cross(const Vector3T& rhs) const throw() { Vector3T vResult; vResult.Cross(*this, rhs); return vResult; }