/** * Find intersections of hyperbolic arm with an axes-aligned line segment. Arm must intersect * segment, not its underlying (infinite) line. The intersection points are sorted into increasing * parameter values w.r.t. the arm. * * @param s0 : start of line segment * @param s1 : end of line segment * @param ipts : intersection points returned here * @param reverseOrder : if true, points are sorted by decreasing parameter values * @param dbFlag : true to print debug information */ public void findOrthogonalIntersect( FPoint2 s0, FPoint2 s1, DArray ipts, boolean reverseOrder, boolean dbFlag) { final boolean db = true && dbFlag; if (db) { System.out.println( "findOrthogonalIntersect " + s0 + " -> " + s1 + " rev:" + Tools.f(reverseOrder)); } // Determine whether this is a vertical or horizontal line segment. boolean vert = (Math.abs(s1.y - s0.y) > Math.abs(s1.x - s0.x)); if (db) { System.out.println(" vert=" + Tools.f(vert)); } // Find the quadratic to solve. Polyn p; PlaneCurve cv = getCurve(); if (vert) { p = cv.solveForX(s0.x); } else { p = cv.solveForY(s0.y); } DArray lst = new DArray(); p.solve(lst); if (db) { System.out.println(" curve=" + cv.toString(true)); System.out.println(" polyn=" + p.toString(true)); System.out.println(" roots=" + Tools.d(lst)); } // Sort points, discarding those not on line segment, // and those not on the correct arm. ipts.clear(); for (int i = 0; i < lst.size(); i++) { double ta = lst.getDouble(i); FPoint2 pt; if (vert) { pt = new FPoint2(s0.x, ta); } else { pt = new FPoint2(ta, s0.y); } if (db) { System.out.println(" position on arm for ta=" + ta + " is " + pt); } double t = MyMath.positionOnSegment(pt, s0, s1); if (db) { System.out.println(" pt=" + pt + " t=" + t); } if (t < 0 || t > 1) { if (db) { System.out.println(" not on segment, skipping"); } continue; } FPoint2 cpt = toCurveSpace(pt, null); if (db) { System.out.println(" curveSpace=" + cpt); } if (cpt.x < 0) { if (db) { System.out.println(" skipping..."); } continue; } double t1 = calcParameter(pt); int j = 0; while (true) { if (j == ipts.size()) { break; } double t2 = calcParameter(ipts.getFPoint2(j)); if (!reverseOrder) { if (t1 < t2) { break; } } else if (t1 > t2) { break; } j++; } ipts.add(j, pt); } if (db) { System.out.println(" ipts=" + Tools.d(ipts)); } }
/** * Find intersections between two hyperbolas * * @param a Hyperbola * @param b Hyperbola * @param iPts where to store intersection points; null to construct */ public static DArray findIntersections(Hyperbola a, Hyperbola b, DArray iPts) { final boolean db = false; if (iPts == null) iPts = new DArray(); iPts.clear(); final DArray jPts = new DArray(); // a.initClipIfNec(); // b.initClipIfNec(); if (db) { System.out.println( "finding intersections between:\n" + a.toString(true) + "\n" + b.toString(true)); } PlaneCurve.findIntersect(a.getCurve(), b.getCurve(), jPts); // filter out false intersections if (db) { System.out.println("prefilter # intersections= " + jPts.size()); } FPoint2 ptc = new FPoint2(); for (int i = 0; i < jPts.size(); i++) { FPoint2 pt = jPts.getFPoint2(i); // make sure calculated intersect point is actually on both arms { FPoint2 data = a.calcParameterAndDistance(pt); if (data.y > .001) continue; data = b.calcParameterAndDistance(pt); if (data.y > .001) continue; } if (!a.isLine()) { // put in curve space to verify it's to the right of the y axis a.toCurveSpace(pt, ptc); if (db) { System.out.println("Filter " + i + " in curveA= " + ptc); } if (ptc.x <= 0) { if (db) { System.out.println(" < 0"); } continue; } } if (!b.isLine()) { b.toCurveSpace(pt, ptc); if (db) { System.out.println(" in curveB= " + ptc); } if (ptc.x <= 0) { if (db) { System.out.println(" < 0"); } continue; } } if (db) { System.out.println(" adding " + pt); } iPts.add(pt); } return iPts; }