use of org.hipparchus.geometry.euclidean.twod.Vector2D in project Orekit by CS-SI.
the class Ellipse method projectToEllipse.
/**
* Project position-velocity-acceleration on an ellipse.
* @param pv position-velocity-acceleration to project, in the reference frame
* @return projected position-velocity-acceleration
*/
public TimeStampedPVCoordinates projectToEllipse(final TimeStampedPVCoordinates pv) {
// find the closest point in the meridian plane
final Vector2D p2D = toPlane(pv.getPosition());
final Vector2D e2D = projectToEllipse(p2D);
// tangent to the ellipse
final double fx = -a2 * e2D.getY();
final double fy = b2 * e2D.getX();
final double f2 = fx * fx + fy * fy;
final double f = FastMath.sqrt(f2);
final Vector2D tangent = new Vector2D(fx / f, fy / f);
// normal to the ellipse (towards interior)
final Vector2D normal = new Vector2D(-tangent.getY(), tangent.getX());
// center of curvature
final double x2 = e2D.getX() * e2D.getX();
final double y2 = e2D.getY() * e2D.getY();
final double eX = evoluteFactorX * x2;
final double eY = evoluteFactorY * y2;
final double omegaX = eX * e2D.getX();
final double omegaY = eY * e2D.getY();
// velocity projection ratio
final double rho = FastMath.hypot(e2D.getX() - omegaX, e2D.getY() - omegaY);
final double d = FastMath.hypot(p2D.getX() - omegaX, p2D.getY() - omegaY);
final double projectionRatio = rho / d;
// tangential velocity
final Vector2D pDot2D = new Vector2D(Vector3D.dotProduct(pv.getVelocity(), u), Vector3D.dotProduct(pv.getVelocity(), v));
final double pDotTangent = pDot2D.dotProduct(tangent);
final double pDotNormal = pDot2D.dotProduct(normal);
final double eDotTangent = projectionRatio * pDotTangent;
final Vector2D eDot2D = new Vector2D(eDotTangent, tangent);
final Vector2D tangentDot = new Vector2D(a2 * b2 * (e2D.getX() * eDot2D.getY() - e2D.getY() * eDot2D.getX()) / f2, normal);
// velocity of the center of curvature in the meridian plane
final double omegaXDot = 3 * eX * eDotTangent * tangent.getX();
final double omegaYDot = 3 * eY * eDotTangent * tangent.getY();
// derivative of the projection ratio
final double voz = omegaXDot * tangent.getY() - omegaYDot * tangent.getX();
final double vsz = -pDotNormal;
final double projectionRatioDot = ((rho - d) * voz - rho * vsz) / (d * d);
// acceleration
final Vector2D pDotDot2D = new Vector2D(Vector3D.dotProduct(pv.getAcceleration(), u), Vector3D.dotProduct(pv.getAcceleration(), v));
final double pDotDotTangent = pDotDot2D.dotProduct(tangent);
final double pDotTangentDot = pDot2D.dotProduct(tangentDot);
final double eDotDotTangent = projectionRatio * (pDotDotTangent + pDotTangentDot) + projectionRatioDot * pDotTangent;
final Vector2D eDotDot2D = new Vector2D(eDotDotTangent, tangent, eDotTangent, tangentDot);
// back to 3D
final Vector3D e3D = toSpace(e2D);
final Vector3D eDot3D = new Vector3D(eDot2D.getX(), u, eDot2D.getY(), v);
final Vector3D eDotDot3D = new Vector3D(eDotDot2D.getX(), u, eDotDot2D.getY(), v);
return new TimeStampedPVCoordinates(pv.getDate(), e3D, eDot3D, eDotDot3D);
}
use of org.hipparchus.geometry.euclidean.twod.Vector2D in project Orekit by CS-SI.
the class OneAxisEllipsoid method projectToGround.
/**
* {@inheritDoc}
*/
public Vector3D projectToGround(final Vector3D point, final AbsoluteDate date, final Frame frame) throws OrekitException {
// transform point to body frame
final Transform toBody = frame.getTransformTo(bodyFrame, date);
final Vector3D p = toBody.transformPosition(point);
final double z = p.getZ();
final double r = FastMath.hypot(p.getX(), p.getY());
// set up the 2D meridian ellipse
final Ellipse meridian = new Ellipse(Vector3D.ZERO, new Vector3D(p.getX() / r, p.getY() / r, 0), Vector3D.PLUS_K, getA(), getC(), bodyFrame);
// find the closest point in the meridian plane
final Vector3D groundPoint = meridian.toSpace(meridian.projectToEllipse(new Vector2D(r, z)));
// transform point back to initial frame
return toBody.getInverse().transformPosition(groundPoint);
}
use of org.hipparchus.geometry.euclidean.twod.Vector2D in project Orekit by CS-SI.
the class Ellipsoid method pointOnLimb.
/**
* Find a point on ellipsoid limb, as seen by an external observer.
* @param observer observer position in ellipsoid frame
* @param outside point outside ellipsoid in ellipsoid frame, defining the phase around limb
* @return point on ellipsoid limb
* @exception OrekitException if the observer is inside the ellipsoid
* @exception MathRuntimeException if ellipsoid center, observer and outside
* points are aligned
* @since 7.1
*/
public Vector3D pointOnLimb(final Vector3D observer, final Vector3D outside) throws OrekitException, MathRuntimeException {
// there is no limb if we are inside the ellipsoid
if (isInside(observer)) {
throw new OrekitException(OrekitMessages.POINT_INSIDE_ELLIPSOID);
}
// cut the ellipsoid, to find an elliptical plane section
final Vector3D normal = Vector3D.crossProduct(observer, outside);
final Ellipse section = getPlaneSection(Vector3D.ZERO, normal);
final double a2 = section.getA() * section.getA();
final double b2 = section.getB() * section.getB();
// the point on limb is tangential to the ellipse
// if T(xt, yt) is an ellipse point at which the tangent is drawn
// if O(xo, yo) is a point outside of the ellipse belonging to the tangent at T,
// then the two following equations holds:
// a² yt² + b² xt² = a² b² (T belongs to the ellipse)
// a² yt yo + b² xt xo = a² b² (TP is tangent to the ellipse)
// using the second equation to eliminate yt from the first equation, we get
// b² (a² - xt xo)² + a² xt² yo² = a⁴ yo²
// (a² yo² + b² xo²) xt² - 2 a² b² xo xt + a⁴ (b² - yo²) = 0
// which can easily be solved for xt
final Vector2D observer2D = section.toPlane(observer);
final double xo = observer2D.getX();
final double yo = observer2D.getY();
final double xo2 = xo * xo;
final double yo2 = yo * yo;
final double alpha = a2 * yo2 + b2 * xo2;
final double beta = a2 * b2 * xo;
final double gamma = a2 * a2 * (b2 - yo2);
// we know there are two solutions as we already checked the point is outside ellipsoid
final double sqrt = FastMath.sqrt(beta * beta - alpha * gamma);
final double xt1;
final double xt2;
if (beta > 0) {
final double s = beta + sqrt;
xt1 = s / alpha;
xt2 = gamma / s;
} else {
final double s = beta - sqrt;
xt1 = gamma / s;
xt2 = s / alpha;
}
// we return the limb point in the direction of the outside point
final Vector3D t1 = section.toSpace(new Vector2D(xt1, b2 * (a2 - xt1 * xo) / (a2 * yo)));
final Vector3D t2 = section.toSpace(new Vector2D(xt2, b2 * (a2 - xt2 * xo) / (a2 * yo)));
return Vector3D.distance(t1, outside) <= Vector3D.distance(t2, outside) ? t1 : t2;
}
use of org.hipparchus.geometry.euclidean.twod.Vector2D in project Orekit by CS-SI.
the class EllipseTest method testMaxRadiusOfCurvature.
@Test
public void testMaxRadiusOfCurvature() {
final double a = 100.0;
final double b = 50.0;
Ellipse e = new Ellipse(Vector3D.ZERO, Vector3D.PLUS_I, Vector3D.PLUS_J, a, b, FramesFactory.getGCRF());
Vector2D point = new Vector2D(0.0, 10 * b);
Assert.assertEquals(a * a / b, Vector2D.distance(e.projectToEllipse(point), e.getCenterOfCurvature(point)), 1.0e-15);
}
use of org.hipparchus.geometry.euclidean.twod.Vector2D in project Orekit by CS-SI.
the class EllipseTest method testMinRadiusOfCurvature.
@Test
public void testMinRadiusOfCurvature() {
final double a = 100.0;
final double b = 50.0;
Ellipse e = new Ellipse(Vector3D.ZERO, Vector3D.PLUS_I, Vector3D.PLUS_J, a, b, FramesFactory.getGCRF());
Vector2D point = new Vector2D(10 * a, 0.0);
Assert.assertEquals(b * b / a, Vector2D.distance(e.projectToEllipse(point), e.getCenterOfCurvature(point)), 1.0e-15);
}
Aggregations