/** * Clip out a section of the arm, using internal parameter values * * @param c0 : start of section to clip out * @param c1 : end of section to clip out; if < c0, c0 & c1 are swapped */ private void clip0(double c0, double c1) { final boolean db = false; if (c0 > c1) { double t = c0; c0 = c1; c1 = t; } // array to store new clip elements in DArray nc = new DArray(); if (db) { System.out.println("clip " + Tools.f(c0) + "..." + Tools.f(c1)); } for (int i = 0; i < visSeg.size(); i += 2) { double t0 = visSeg.getDouble(i), t1 = visSeg.getDouble(i + 1); if (db) { System.out.println(" seg " + i + " " + Tools.f(t0) + "..." + Tools.f(t1)); } // if this seg is outside clip region, leave intact (add it) if (t0 >= c1 || t1 <= c0) { nc.addDouble(t0); nc.addDouble(t1); continue; } if (t0 >= c0 && t1 <= c1) { if (db) { System.out.println(" clipping entire segment"); } // remove entire segment, by skipping it continue; } // add unclipped portion if (t0 < c0) { nc.addDouble(t0); nc.addDouble(c0); } if (t1 > c1) { nc.addDouble(c1); nc.addDouble(t1); } } visSeg = nc; if (db) { System.out.println(" after clipping:" + visSeg); } }
/** * Determine closest point on hyperbolic arm to a point pt * * @param pt : point * @return t value for closest point; not necessarily within clipped range */ public double closestPointTo(FPoint2 pt) { final boolean db = false; pt = toCurveSpace(pt, null); double U = B + 1; double V = -pt.y; double W = B * pt.x; Polyn p = new Polyn( // B * U * U, // 2 * B * U * V, // B * V * V + A * U * U - W * W, // 2 * A * U * V, // A * V * V // ); if (db) Streams.out.println("closestPointTo, pt=" + pt + "\n" + p); double ret = 0; try { DArray r = new DArray(); if (Math.abs(p.c(0)) < 1e-5) r.addDouble(0); else p.solve(r); if (r.isEmpty()) { throw new FPError("can't find closest point, poly=\n" + p); } double bestDist = 0; for (int i = 0; i < r.size(); i++) { double t = r.getDouble(i); FPoint2 apt = calcPoint(t); double dist = apt.distance(pt); if (i == 0 || dist < bestDist) { bestDist = dist; ret = t; } } } catch (FPError e) { Tools.warn("caught FPError"); // Streams.out.println("caught:\n" + e); ret = (this.minParameter() + this.maxParameter()) * .5; } return ret; }