/**
     * constructor to create a view
     *
     * @param projection: projection image as Grid2D
     * @param radon: radon transformed and derived image as Grid2D
     * @param projMatrix: projection matrix as Projection
     */
    public View(Grid2D projection, Grid2D radon, Projection projMatrix) {

      // Initialize center matrix //
      CENTER = new SimpleMatrix(3, 4);
      CENTER.setDiagValue(new SimpleVector(1.0, 1.0, 1.0));

      // get data out of projection //
      this.projectionWidth = projection.getWidth();
      this.projectionHeight = projection.getHeight();

      // get data out of radon transformed image //
      this.radonWidth = radon.getWidth();
      this.radonHeight = radon.getHeight();
      this.projectionDiag =
          Math.sqrt(projectionWidth * projectionWidth + projectionHeight * projectionHeight);
      this.lineIncrement = radonWidth / projectionDiag;
      this.angleIncrement = radonHeight / Math.PI;

      // store radon transformed image //
      this.radon = radon;

      // get projection matrix P (3x4) //
      this.P = SimpleOperators.multiplyMatrixProd(projMatrix.getK(), CENTER);
      this.P = SimpleOperators.multiplyMatrixProd(this.P, projMatrix.getRt());

      // get source position C (nullspace of the projection) //
      DecompositionSVD decoP = new DecompositionSVD(this.P);
      this.C = decoP.getV().getCol(3);

      // normalize source vectors by last component //
      // it is important that the last component is positive to have a positive center
      // as it is defined in oriented projective geometry
      this.C = this.C.dividedBy(this.C.getElement(3));
    }
  /**
   * method to calculate a mapping K from two source positions C0, C1 to a plane C0 (C1) is the
   * source position from the first (second) view
   */
  public void createMappingToEpipolarPlane() {

    // set up source matrices //
    SimpleVector C0 = this.view1.C;
    SimpleVector C1 = this.view2.C;

    // compute Pluecker coordinates //
    double L01 = C0.getElement(0) * C1.getElement(1) - C0.getElement(1) * C1.getElement(0);
    double L02 = C0.getElement(0) * C1.getElement(2) - C0.getElement(2) * C1.getElement(0);
    double L03 = C0.getElement(0) * C1.getElement(3) - C0.getElement(3) * C1.getElement(0);
    double L12 = C0.getElement(1) * C1.getElement(2) - C0.getElement(2) * C1.getElement(1);
    double L13 = C0.getElement(1) * C1.getElement(3) - C0.getElement(3) * C1.getElement(1);
    double L23 = C0.getElement(2) * C1.getElement(3) - C0.getElement(3) * C1.getElement(2);

    // construct B (6x1) //
    SimpleVector B = new SimpleVector(L01, L02, L03, L12, L13, L23);

    // compute infinity point in direction of B //
    SimpleVector N = new SimpleVector(-L03, -L13, -L23, 0);

    // compute plane E0 containing B and X0=(0,0,0,1) //
    SimpleVector E0 = SimpleOperators.getPlueckerJoin(B, new SimpleVector(0, 0, 0, 1));

    // find othonormal basis from plane normals //
    // (vectors are of 3x1)
    SimpleVector a2 = new SimpleVector(E0.getElement(0), E0.getElement(1), E0.getElement(2));
    SimpleVector a3 = new SimpleVector(N.getElement(0), N.getElement(1), N.getElement(2));
    // set vectors to unit length
    a2.normalizeL2();
    a3.normalizeL2();

    // calculate cross product to get the last basis vector //
    SimpleVector a1 = General.crossProduct(a2, a3).negated();
    // (a1 is already of unit length -> no normalization needed)

    // set up assembly matrix A (4x3) //
    SimpleMatrix A = new SimpleMatrix(4, 3);
    A.setSubColValue(0, 0, a1);
    A.setSubColValue(0, 1, a2);
    A.setSubColValue(0, 2, C0);

    // store mapping matrix K (4x3 = 4x4 * 4x3) //
    this.K = SimpleOperators.multiplyMatrixProd(SimpleOperators.getPlueckerMatrixDual(B), A);
  }