Calculates intersections of a line segment with a circle Author N.Vischer ax, ay, bx, by: points A and B of line segment cx, cy, rad: Circle center and radius. ignoreOutside: if true, ignores intersections outside the line segment A-B Returns an array of 0, 2 or 4 coordinates (for 0, 1, or 2 i
(double ax, double ay, double bx, double by, double cx, double cy, double rad, boolean ignoreOutside)
| 823 | * </pre> |
| 824 | */ |
| 825 | public static double[] lineCircleIntersection(double ax, double ay, double bx, double by, double cx, double cy, double rad, boolean ignoreOutside) { |
| 826 | //rotates & translates points A, B and C, creating new points A2, B2 and C2. |
| 827 | //A2 is then on origin, and B2 is on positive x-axis |
| 828 | |
| 829 | double dxAC = cx - ax; |
| 830 | double dyAC = cy - ay; |
| 831 | double lenAC = Math.sqrt(dxAC * dxAC + dyAC * dyAC); |
| 832 | |
| 833 | double dxAB = bx - ax; |
| 834 | double dyAB = by - ay; |
| 835 | |
| 836 | //calculate B2 and C2: |
| 837 | double xB2 = Math.sqrt(dxAB * dxAB + dyAB * dyAB); |
| 838 | |
| 839 | double phi1 = Math.atan2(dyAB, dxAB);//amount of rotation |
| 840 | double phi2 = Math.atan2(dyAC, dxAC); |
| 841 | double phi3 = phi1 - phi2; |
| 842 | double xC2 = lenAC * Math.cos(phi3); |
| 843 | double yC2 = lenAC * Math.sin(phi3);//rotation & translation is done |
| 844 | if (Math.abs(yC2) > rad) |
| 845 | return new double[0];//no intersection found |
| 846 | double halfChord = Math.sqrt(rad * rad - yC2 * yC2); |
| 847 | double sectOne = xC2 - halfChord;//first intersection point, still on x axis |
| 848 | double sectTwo = xC2 + halfChord;//second intersection point, still on x axis |
| 849 | double[] xyCoords = new double[4]; |
| 850 | int ptr = 0; |
| 851 | if ((sectOne >= 0 && sectOne <= xB2) || !ignoreOutside) { |
| 852 | double sectOneX = Math.cos(phi1) * sectOne + ax;//undo rotation and translation |
| 853 | double sectOneY = Math.sin(phi1) * sectOne + ay; |
| 854 | xyCoords[ptr++] = sectOneX; |
| 855 | xyCoords[ptr++] = sectOneY; |
| 856 | } |
| 857 | if ((sectTwo >= 0 && sectTwo <= xB2) || !ignoreOutside) { |
| 858 | double sectTwoX = Math.cos(phi1) * sectTwo + ax;//undo rotation and translation |
| 859 | double sectTwoY = Math.sin(phi1) * sectTwo + ay; |
| 860 | xyCoords[ptr++] = sectTwoX; |
| 861 | xyCoords[ptr++] = sectTwoY; |
| 862 | } |
| 863 | if (halfChord == 0 && ptr > 2) //tangent line returns only one intersection |
| 864 | ptr = 2; |
| 865 | xyCoords = java.util.Arrays.copyOf(xyCoords,ptr); |
| 866 | return xyCoords; |
| 867 | } |
| 868 | |
| 869 | /** Returns a copy of this roi. See Thinking is Java by Bruce Eckel |
| 870 | (www.eckelobjects.com) for a good description of object cloning. */ |
no test coverage detected