/**
  * Draw the decoration. If the curve is null when this is called, then curve will be set to the
  * exhibit displayed in the View, which should be of type PlaneCurveParameteric, if this
  * decoration is being used correctly.
  */
 public void doDraw(Graphics2D g, View view, Transform limits) {
   if (curve == null && view != null) {
     Exhibit c = view.getExhibit();
     if (c instanceof PlaneCurveParametric) // It better be!
     curve = (PlaneCurveParametric) c;
     else return;
   }
   if (Double.isNaN(t)) return;
   double x = curve.xValue(t);
   if (Double.isNaN(x) || Double.isInfinite(x)) return;
   double y = curve.yValue(t);
   if (Double.isNaN(y) || Double.isInfinite(y)) return;
   double dx = curve.xDerivativeValue(t);
   if (Double.isNaN(dx) || Double.isInfinite(dx)) return;
   double dy = curve.yDerivativeValue(t);
   if (Double.isNaN(dy) || Double.isInfinite(dy)) return;
   double length = Math.sqrt(dx * dx + dy * dy);
   if (length == 0) return;
   dx = dx / length * 40 * limits.getPixelWidth();
   dy = dy / length * 40 * limits.getPixelHeight();
   Color saveColor = g.getColor();
   Stroke saveStroke = g.getStroke();
   g.setStroke(new BasicStroke(2 * limits.getDefaultStrokeSize()));
   g.setColor(Color.red);
   g.draw(new Line2D.Double(x, y, x + dx, y + dy));
   g.setColor(Color.blue);
   g.draw(new Line2D.Double(x, y, x - dy, y + dx));
   g.setColor(saveColor);
   g.setStroke(saveStroke);
 }
 /**
  * Set the t-value to be at one of the points that are used for drawing the curve. If the curve is
  * null when this is called, it has no effect.
  *
  * @param tIndex An index into the array of t-values that the curve uses to generate the curve.
  *     The index should be in the legal range; if not, nothing is drawn. The range is from 0 to
  *     getCurve().getPointCount().
  */
 public void setIndex(int tIndex) {
   if (curve != null) setT(curve.getT(tIndex));
 }