Example #1
0
  public DefrisePhantom() {

    Trajectory trajectory = Configuration.getGlobalConfiguration().getGeometry();

    double sourceAxisDistance = trajectory.getSourceToAxisDistance();
    double sourceDetectorDistance = trajectory.getSourceToDetectorDistance();
    double detectorYAxis = trajectory.getDetectorHeight() * trajectory.getPixelDimensionY();
    double detectorXAxis = trajectory.getDetectorWidth() * trajectory.getPixelDimensionX();

    double fovRadius = detectorXAxis * sourceAxisDistance / sourceDetectorDistance / 2 * 0.95;
    double diskRadius = 4.0 / 5.0 * fovRadius;
    double fovHeight = detectorYAxis * sourceAxisDistance / sourceDetectorDistance;
    double diskHeight = fovHeight / 15.0;
    double diskSpacing = fovHeight / 15.0;
    int numDisks = 5;
    double diskStart =
        -(fovHeight / 2.0)
            + ((fovHeight - (numDisks * diskHeight + diskSpacing * (numDisks - 1))) / 2.0)
            + diskHeight / 2.0;

    // Water Body
    Cylinder cyl = new Cylinder(fovRadius, fovRadius, fovHeight);
    cyl.setName("Water-like body of the phantom");
    PhysicalObject po = new PhysicalObject();
    po.setMaterial(MaterialsDB.getMaterialWithName("Water")); // D = 1.0
    po.setShape(cyl);
    add(po);

    // Disk Inserts
    for (int i = 0; i < numDisks; i++) {
      cyl = new Cylinder(diskRadius, diskRadius, diskHeight);
      cyl.setName("Disk");
      cyl.applyTransform(
          new Translation(new SimpleVector(0, 0, diskStart + (diskSpacing + diskHeight) * i)));
      po = new PhysicalObject();
      po.setMaterial(MaterialsDB.getMaterialWithName("Plexiglass")); // D = 1.95
      po.setShape(cyl);
      add(po);
    }
  }
  public Grid2D raytraceScene(PrioritizableScene phantomScene, Projection projection) {
    Trajectory geom = Configuration.getGlobalConfiguration().getGeometry();
    // Grid2D slice = new Grid2D(geom.getDetectorWidth(), geom.getDetectorHeight());
    Grid2D slice =
        detector.createDetectorGrid(geom.getDetectorWidth(), geom.getDetectorHeight(), projection);
    rayTracer.setScene(phantomScene);
    // Second rule of optimization is: Optimize later.
    PointND raySource = new PointND(0, 0, 0);
    raySource.setCoordinates(projection.computeCameraCenter());
    StraightLine castLine = new StraightLine(raySource, new SimpleVector(0, 0, 0));

    SimpleVector centerPixDir = null;
    if (accurate) {
      centerPixDir = projection.computePrincipalAxis();
    }
    // SimpleVector prinpoint = trajectory.getProjectionMatrix(sliceNumber).getPrincipalPoint();

    double xcorr = 0; // trajectory.getDetectorWidth()/2 - prinpoint.getElement(0);
    double ycorr = 0; // trajectory.getDetectorHeight()/2 - prinpoint.getElement(1);

    double length = trajectory.getSourceToDetectorDistance();
    Edge environmentEdge = new Edge(new PointND(0), new PointND(length));

    ArrayList<PhysicalObject> fallBackBackground = new ArrayList<PhysicalObject>(1);
    SimpleVector pixel = new SimpleVector(0, 0);
    boolean negate = false;
    for (int y = 0; y < trajectory.getDetectorHeight(); y++) {
      for (int x = 0; x < trajectory.getDetectorWidth(); x++) {
        pixel.setElementValue(0, x - xcorr);
        pixel.setElementValue(1, y - ycorr);
        SimpleVector dir = projection.computeRayDirection(pixel);
        if ((y == 0) && (x == 0)) {
          // Check that ray direction is towards origin.
          double max = 0;
          int index = 0;
          for (int i = 0; i < 3; i++) {
            if (Math.abs(dir.getElement(i)) > max) {
              max = Math.abs(dir.getElement(i));
              index = i;
            }
          }
          double t = -raySource.get(index) / dir.getElement(index);
          if (t < 0) negate = true;
        }
        if (negate) dir.negate();
        castLine.setDirection(dir);

        ArrayList<PhysicalObject> segments = rayTracer.castRay(castLine);
        if (accurate) {
          double dirCosine = SimpleOperators.multiplyInnerProd(centerPixDir, dir);
          length = trajectory.getSourceToDetectorDistance() / dirCosine;
        }

        if (segments == null) {
          fallBackBackground.clear();
          segments = fallBackBackground;
        } else {
          if (accurate) {
            environmentEdge =
                new Edge(new PointND(0), new PointND(length - getTotalSegmentsLength(segments)));
          }
        }
        environment.setShape(environmentEdge);
        segments.add(environment);
        /* old code:
        double integral = absorptionModel.evaluateLineIntegral(segments);

        slice.putPixelValue(x, y, integral);
         */
        detector.writeToDetector(slice, x, y, segments);
      }
    }
    return slice;
  }