protected void initElements() {
    super.initElements();

    for (int i = 0; i < P.length; i++) {
      setOutputDependencies(P[i]);
    }

    tMin = g.getMinParameter();
    tMax = g.getMaxParameter();

    Color BLUE_VIOLET = new Color(153, 0, 255);
    int THICK_LINE_WITHIN_LINE = 4;

    // TODO: this initialization of input assumes the type
    // of the line and the conic
    // and will NOT update anymore.
    // should change to a more dynamic version.
    lines = new GeoLine[4];
    lines[0] = (GeoLine) g.copyInternal(cons);
    if (Double.isInfinite(tMin)) lines[1] = new GeoRay(cons);
    else lines[1] = new GeoSegment(cons);
    lines[2] = new GeoSegment(cons);
    if (Double.isInfinite(tMax)) lines[3] = new GeoRay(cons);
    else lines[3] = new GeoSegment(cons);

    for (int i = 0; i < 4; i++) {
      setOutputDependencies(lines[i]);
      lines[i].setLineThickness(THICK_LINE_WITHIN_LINE);
      lines[i].setObjColor(BLUE_VIOLET);
    }

    // paramSet.add(tMin);
    // paramSet.add(tMax);
  }
  protected void compute() {
    super.compute();

    numberOfPoints = 0;
    for (int i = 0; i < P.length; i++) {
      if (P[i].isDefined()) numberOfPoints++;
    }

    // build lines
    numberOfOutputLines = 0;
    initCurrentPartIsInRegion();

    switch (intersectionType) {
      case INTERSECTION_PRODUCING_LINE: // contained in degenerate conic
      case INTERSECTION_ASYMPTOTIC_LINE: // intersect at no point
      case INTERSECTION_PASSING_LINE: // intersect at no point
        lines[1].setUndefined();
        lines[2].setUndefined();
        lines[3].setUndefined();

        if (!currentPartIsInRegion) lines[0].setUndefined();
        else {
          lines[0].set(g);
          numberOfOutputLines++;
        }
        break;
      case INTERSECTION_MEETING_LINE:
        lines[0].setUndefined();
        lines[2].setUndefined();

        if (currentPartIsInRegion) {
          lines[3].setUndefined();
          // set line[1]
          double t = g.getPossibleParameter(Q[0].getCoords());

          if (tMin.isInfinite()) {
            ((GeoRay) lines[1]).set(Q[0], g);
            lines[1].changeSign();
            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(tMin, t)) lines[1].setUndefined();
            else {
              ((GeoSegment) lines[3]).set(Q[0], g.endPoint, g);
              numberOfOutputLines++;
            }
          }

        } else {
          lines[1].setUndefined();
          // set line[3]
          double t = g.getPossibleParameter(Q[0].getCoords());

          if (tMax.isInfinite()) {
            ((GeoRay) lines[3]).set(Q[0], g);
            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(tMin, t)) lines[1].setUndefined();
            else {
              ((GeoSegment) lines[3]).set(Q[0], g.endPoint, g);
              numberOfOutputLines++;
            }
          }
        }
        break;

      case INTERSECTION_TANGENT_LINE: // tangent at one point
        lines[0].setUndefined();

        if (currentPartIsInRegion) {
          // set line[1] and line[3]
          double t = g.getPossibleParameter(Q[0].getCoords());

          if (tMin.isInfinite()) {
            ((GeoRay) lines[1]).set(Q[0], g);
            lines[1].changeSign();

            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(tMin, t)) lines[1].setUndefined();
            else {
              ((GeoSegment) lines[3]).set(Q[0], g.endPoint, g);
              numberOfOutputLines++;
            }
          }

          if (tMax.isInfinite()) {
            ((GeoRay) lines[3]).set(Q[0], g);
            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(tMin, t)) lines[1].setUndefined();
            else {
              ((GeoSegment) lines[3]).set(Q[0], g.endPoint, g);
              numberOfOutputLines++;
            }
          }
        } else {
          lines[1].setUndefined();
          lines[3].setUndefined();
        }
        break;
      case INTERSECTION_SECANT_LINE: // intersect at two points

        // get parameters of two intersection points
        double t1 = g.getPossibleParameter(Q[0].getCoords());
        double t2 = g.getPossibleParameter(Q[1].getCoords());
        int j0 = 0;
        int j1 = 1;

        // let t1<=t2. if not, swap the index of the points
        if (t1 > t2) {
          double temp = t1;
          t1 = t2;
          t2 = temp;
          j1 = 0;
          j0 = 1;
        }

        lines[0].setUndefined();
        if (currentPartIsInRegion) {
          lines[2].setUndefined();

          // set line[1] and line[3]

          if (tMin.isInfinite()) {
            ((GeoRay) lines[1]).set(Q[j0], g);
            lines[1].changeSign();
            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(tMin, t1)) lines[1].setUndefined();
            else {
              ((GeoSegment) lines[1]).set(Q[j0], g.endPoint, g);
              numberOfOutputLines++;
            }
          }

          if (tMax.isInfinite()) {
            ((GeoRay) lines[3]).set(Q[j1], g);
            numberOfOutputLines++;
          } else {
            if (Kernel.isGreater(t2, tMax)) lines[3].setUndefined();
            else {
              ((GeoSegment) lines[3]).set(Q[j1], g.endPoint, g);
              numberOfOutputLines++;
            }
          }
        } else {
          lines[1].setUndefined();
          lines[3].setUndefined();

          // set line[2]

          if (Kernel.isGreater(t1, tMax) || Kernel.isGreater(tMin, t2)) lines[2].setUndefined();
          else {
            ((GeoSegment) lines[2])
                .set(
                    Kernel.isGreater(tMin, t1) ? g.startPoint : Q[j0],
                    Kernel.isGreater(t2, tMax) ? g.endPoint : Q[j1],
                    g);
            numberOfOutputLines++;
          }
        }
        break;
    }

    refreshOutput();

    setLabelsForPointsAndLines();
  }