Ejemplo n.º 1
0
 /**
  * Attempts to return a rotation matrix corresponding to moving the plane between two cursor
  * positions, with a given initial rotation matrix in effect.
  *
  * @param rot0 initial rotation matrix
  * @param pos0 initial projected position
  * @param pos1 destination projected position
  * @return destination rotation matrix, or null
  * @see Projection#projRotate
  */
 private double[] genericRotate(double[] rot0, Point2D.Double pos0, Point2D.Double pos1) {
   double[] rv0 = new double[3];
   if (unproject(pos0, rv0)
       && getSkyviewProjecter().validPosition(new double[] {pos1.x, pos1.y})) {
     double[] unrot0 = Matrices.invert(rot0);
     double[] ru0 = Matrices.mvMult(unrot0, rv0);
     return getRotation(ru0, pos1, rot0);
   } else {
     return null;
   }
 }
Ejemplo n.º 2
0
  @Override
  public double[] cursorRotate(double[] rot0, Point2D.Double pos0, Point2D.Double pos1) {

    /* Attempt the rotation that transforms a point from one
     * projected plane position to another. */
    double[] rot1 = genericRotate(rot0, pos0, pos1);
    if (rot1 != null) {
      return rot1;
    }

    /* That may fail because one or other of the supplied points is
     * not in the projection region.  In that case do something
     * that feels like dragging the sphere around.
     * This rotation could be improved.  It is algebraically messy,
     * and it also does not transition smoothly from the genericRotate
     * case, though perhaps that's not possible in general. */
    else {
      boolean reflect = isReflected(rot0);
      double fr = reflect ? -1 : +1;
      double phi = (pos1.x - pos0.x);
      double psi = (pos1.y - pos0.y);
      double[] rm = rot0;
      double[] sightvec = Matrices.mvMult(Matrices.invert(rm), new double[] {1, 0, 0});
      double[] hvec = Matrices.normalise(Matrices.cross(sightvec, RZ));
      rm = rotateAround(rm, hvec, -psi);
      rm = rotateAround(rm, RZ, -phi * fr);
      if (Matrices.mvMult(rm, RZ)[2] >= 0) {
        return rm;
      } else {
        double delta = Math.atan2(-rm[2], rm[8]);
        double alpha = Math.atan2(-rm[3], rm[4] * fr);
        delta = Math.min(+0.5 * Math.PI, delta);
        delta = Math.max(-0.5 * Math.PI, delta);
        return verticalRotate(delta, alpha, reflect);
      }
    }
  }