Esempio n. 1
0
  private void getMinMax(double p1, double p2, double p3, double p4, double[] minMax) {
    if (p4 > p1) {
      minMax[0] = p1;
      minMax[1] = p4;
    } else {
      minMax[0] = p4;
      minMax[1] = p1;
    }

    double c0 = 3 * (p2 - p1);
    double c1 = 6 * (p3 - p2);
    double c2 = 3 * (p4 - p3);
    double[] eqn = {c0, c1 - 2 * c0, c2 - c1 + c0};
    int roots = QuadCurve2D.solveQuadratic(eqn);
    for (int r = 0; r < roots; r++) {
      double tv = eqn[r];
      if ((tv <= 0) || (tv >= 1)) continue;
      tv =
          ((1 - tv) * (1 - tv) * (1 - tv) * p1
              + 3 * tv * (1 - tv) * (1 - tv) * p2
              + 3 * tv * tv * (1 - tv) * p3
              + tv * tv * tv * p4);
      if (tv < minMax[0]) minMax[0] = tv;
      else if (tv > minMax[1]) minMax[1] = tv;
    }
  }
Esempio n. 2
0
 @Override
 public Point2D calculatePosition(Point2D pos, double speed) {
   if (isBackWard) {}
   PathIterator p = fCurve.getPathIterator(null);
   FlatteningPathIterator f = new FlatteningPathIterator(p, reduceCarSpeed(speed));
   while (!f.isDone()) {
     float[] pts = new float[6];
     switch (f.currentSegment(pts)) {
       case PathIterator.SEG_MOVETO:
       case PathIterator.SEG_LINETO:
         Point2D point = new Point2D.Float(pts[0], pts[1]);
         if (point.distance(pos) == 0) {
           f.next();
           if (!f.isDone()) {
             pts = new float[6];
             f.currentSegment(pts);
             return new Point2D.Float(pts[0], pts[1]);
           } else {
             return new Point2D.Double(-1, -1);
           }
         }
     }
     f.next();
   }
   return new Point2D.Double(-1, -1);
 }
  /** Initializes object to draw given edge. */
  private void updateCurve(VisualEdge e) {
    Vec2 fromPos = e.getFrom().getVisibleAncestor().getPos();
    Vec2 toPos = e.getTo().getVisibleAncestor().getPos();

    Vec2 curveCenter = e.getPos();
    // second control point
    double px = 2 * (curveCenter.x - 0.25 * fromPos.x - 0.25 * toPos.x);
    double py = 2 * (curveCenter.y - 0.25 * fromPos.y - 0.25 * toPos.y);
    if (curve == null) curve = new QuadCurve2D.Double();

    curve.setCurve(fromPos.x, fromPos.y, px, py, toPos.x, toPos.y);
  }
Esempio n. 4
0
 private static CubicCurve2D _toCubicCurve(Shape seg, CubicCurve2D cub) {
   if (cub == null) {
     cub = new CubicCurve2D.Double();
   }
   if (seg instanceof Line2D) {
     Line2D src = (Line2D) seg;
     cub.setCurve(
         src.getX1(),
         src.getY1(),
         src.getX1(),
         src.getY1(),
         src.getX2(),
         src.getY2(),
         src.getX2(),
         src.getY2());
   } else if (seg instanceof Ellipse2D) {
     throw new InternalError("Can't convert Ellipse2D to CubicCurve2D");
   } else if (seg instanceof Arc2D) {
     throw new InternalError("Can't convert Arc2D to CubicCurve2D");
   } else if (seg instanceof QuadCurve2D) {
     QuadCurve2D src = (QuadCurve2D) seg;
     cub.setCurve(
         src.getX1(),
         src.getY1(),
         src.getCtrlX(),
         src.getCtrlY(),
         src.getCtrlX(),
         src.getCtrlY(),
         src.getX2(),
         src.getY2());
   } else {
     CubicCurve2D src = (CubicCurve2D) seg;
     cub.setCurve(
         src.getX1(),
         src.getY1(),
         src.getCtrlX1(),
         src.getCtrlY1(),
         src.getCtrlX2(),
         src.getCtrlY2(),
         src.getX2(),
         src.getY2());
   }
   return cub;
 }
Esempio n. 5
0
    @Override
    public boolean contains(Location loc, boolean assumeFilled) {
        Object type = getPaintType();
        if (assumeFilled && type == DrawAttr.PAINT_STROKE) {
            type = DrawAttr.PAINT_STROKE_FILL;
        }
        if (type != DrawAttr.PAINT_FILL) {
            int stroke = getStrokeWidth();
            double[] q = toArray(loc);
            double[] p0 = toArray(this.p0);
            double[] p1 = toArray(this.p1);
            double[] p2 = toArray(this.p2);
            double[] p = CurveUtil.findNearestPoint(q, p0, p1, p2);
            if (p == null) {
                return false;
            }


            int thr;
            if (type == DrawAttr.PAINT_STROKE) {
                thr = Math.max(Line.ON_LINE_THRESH, stroke / 2);
            } else {
                thr = stroke / 2;
            }
            if (LineUtil.distanceSquared(p[0], p[1], q[0], q[1]) < thr * thr) {
                return true;
            }
        }
        if (type != DrawAttr.PAINT_STROKE) {
            QuadCurve2D curve = getCurve(null);
            if (curve.contains(loc.getX(), loc.getY())) {
                return true;
            }
        }
        return false;
    }
Esempio n. 6
0
 /**
  * determines whether the car is still on this lane
  *
  * @param fCar car to test with
  * @param lane
  * @return
  */
 public boolean carOnLane(Car fCar, Lane lane) {
   PathIterator p = fCurve.getPathIterator(null);
   FlatteningPathIterator f = new FlatteningPathIterator(p, reduceCarSpeed(fCar.getSpeed()));
   while (!f.isDone()) {
     float[] pts = new float[6];
     switch (f.currentSegment(pts)) {
       case PathIterator.SEG_MOVETO:
       case PathIterator.SEG_LINETO:
         Point2D point = new Point2D.Float(pts[0], pts[1]);
         if (point.distance(fCar.getPosition()) <= 1) {
           return true;
         }
     }
     f.next();
   }
   return false;
 }
Esempio n. 7
0
  @Override
  public double getLength() {
    if (fLength == 0) {
      PathIterator iter = fCurve.getPathIterator(null, 0.5);

      double[] curSeg = new double[2];
      iter.currentSegment(curSeg);
      iter.next();
      double x0 = curSeg[0];
      double y0 = curSeg[1];
      while (!iter.isDone()) {
        iter.currentSegment(curSeg);
        fLength +=
            Math.sqrt((curSeg[0] - x0) * (curSeg[0] - x0) + (curSeg[1] - y0) * (curSeg[1] - y0));
        x0 = curSeg[0];
        y0 = curSeg[1];
        iter.next();
      }
    }
    return fLength;
  }
Esempio n. 8
0
 @Override
 public void relocate(Car fCar) {
   PathIterator p = fCurve.getPathIterator(null);
   FlatteningPathIterator f = new FlatteningPathIterator(p, reduceCarSpeed(fCar.getSpeed()));
   Point2D nearestPoint = null;
   double distance = 1000;
   while (!f.isDone()) {
     float[] pts = new float[6];
     switch (f.currentSegment(pts)) {
       case PathIterator.SEG_MOVETO:
       case PathIterator.SEG_LINETO:
         Point2D point = new Point2D.Float(pts[0], pts[1]);
         double distance1 = point.distance(fCar.getPosition());
         if (distance1 < distance) {
           nearestPoint = point;
           distance = distance1;
         }
     }
     f.next();
   }
   if (nearestPoint != null) {
     fCar.setPosition(nearestPoint);
   }
 }
Esempio n. 9
0
  /** @see prefuse.render.AbstractShapeRenderer#getRawShape(prefuse.visual.VisualItem) */
  @Override
  protected Shape getRawShape(VisualItem item) {
    EdgeItem e = (EdgeItem) item;
    VisualItem source = e.getSourceItem();
    VisualItem target = e.getTargetItem();

    int type = m_edgeType;
    int edgeIndex = -1;

    getAlignedPoint(m_tmpPoints[0], source.getBounds(), m_xAlign1, m_yAlign1);
    getAlignedPoint(m_tmpPoints[1], target.getBounds(), m_xAlign2, m_yAlign2);
    m_curWidth = (float) (m_width * getLineWidth(item));

    boolean curveCtrlPtsReady = false;
    Polygon arrowHead;
    // create the arrow head, if needed
    if (isDirected(e)
        && m_edgeArrow != Constants.EDGE_ARROW_NONE
        && (arrowHead = getArrowHead(e)) != null) {
      // get starting and ending edge endpoints
      boolean forward = (m_edgeArrow == Constants.EDGE_ARROW_FORWARD);
      Point2D start = null, end = null;
      start = m_tmpPoints[forward ? 0 : 1];
      end = m_tmpPoints[forward ? 1 : 0];
      // compute the intersection with the source/target bounding box
      VisualItem src = getSourceItem(e, forward);
      VisualItem dest = getTargetItem(e, forward);

      if (edgeBounded && !e.isAggregating()) {
        adjustEndingPoint(start, end, src, dest);
      } else if (GraphicsLib.intersectLineRectangle(start, end, dest.getBounds(), m_isctPoints)
          > 0) {
        end.setLocation(m_isctPoints[0]);
      }

      // create the arrow head shape
      AffineTransform arrowTrans;
      if (multipleEdge) {
        edgeIndex = adjustEndingPointByMultipleEdge(e, start, end);
        if (lineForSingleEdge && edgeIndex < 0) {
          type = Constants.EDGE_TYPE_LINE;
          arrowTrans = getArrowTrans(start, end, m_curWidth);
        } else {
          getCurveControlPoints(
              edgeIndex, m_ctrlPoints, start.getX(), start.getY(), end.getX(), end.getY());
          curveCtrlPtsReady = true;
          arrowTrans = getArrowTrans(m_ctrlPoints[0], end, m_curWidth);
        }
      } else {
        arrowTrans = getArrowTrans(start, end, m_curWidth);
      }
      m_curArrow = m_tmpArrow.set(arrowHead, arrowTrans);

      // update the endpoints for the edge shape
      // need to bias this by arrow head size
      adjustLineEndByArrowHead(e, end);
      arrowTrans.transform(end, end);
    } else {
      m_curArrow = null;
      if (edgeBounded && !e.isAggregating()) {
        adjustEndingPoint(m_tmpPoints[0], m_tmpPoints[1], source, target);
      }
      if (multipleEdge) {
        edgeIndex = adjustEndingPointByMultipleEdge(e, m_tmpPoints[0], m_tmpPoints[1]);
        if (lineForSingleEdge && edgeIndex < 0) {
          type = Constants.EDGE_TYPE_LINE;
        } else {
          getCurveControlPoints(
              edgeIndex,
              m_ctrlPoints,
              m_tmpPoints[0].getX(),
              m_tmpPoints[0].getY(),
              m_tmpPoints[1].getX(),
              m_tmpPoints[1].getY());
          curveCtrlPtsReady = true;
        }
      }
    }

    // create the edge shape
    Shape shape = null;
    double sx = m_tmpPoints[0].getX();
    double sy = m_tmpPoints[0].getY();
    double ex = m_tmpPoints[1].getX();
    double ey = m_tmpPoints[1].getY();
    switch (type) {
      case Constants.EDGE_TYPE_LINE:
        m_line.setLine(sx, sy, ex, ey);
        shape = m_line;
        break;
      case Constants.EDGE_TYPE_CURVE:
        if (!curveCtrlPtsReady) {
          getCurveControlPoints(e, m_ctrlPoints, sx, sy, ex, ey);
        }
        m_quad.setCurve(sx, sy, m_ctrlPoints[0].getX(), m_ctrlPoints[0].getY(), ex, ey);
        shape = m_quad;
        break;
      default:
        throw new IllegalStateException("Unknown edge type");
    }

    // return the edge shape
    return shape;
  }
Esempio n. 10
0
 public QuadCurve2D evaluate(QuadCurve2D v0, QuadCurve2D v1, float fraction) {
   double x1 = v0.getX1() + ((v1.getX1() - v0.getX1()) * fraction);
   double y1 = v0.getY1() + ((v1.getY1() - v0.getY1()) * fraction);
   double x2 = v0.getX2() + ((v1.getX2() - v0.getX2()) * fraction);
   double y2 = v0.getY2() + ((v1.getY2() - v0.getY2()) * fraction);
   double ctrlx = v0.getCtrlX() + ((v1.getCtrlX() - v0.getCtrlX()) * fraction);
   double ctrly = v0.getCtrlY() + ((v1.getCtrlY() - v0.getCtrlY()) * fraction);
   QuadCurve2D value = (QuadCurve2D) v0.clone();
   value.setCurve(x1, y1, ctrlx, ctrly, x2, y2);
   return value;
 }