package ru.delkom07.geometry; import ru.delkom07.geometry.obj.LineFunction; public class LineFunctions { /** * Returns line function of given segment. * @param p1 - first point of segment. * @param p2 - second point of segment. * @return line function of given segment. * @tested */ public static LineFunction getLineFunction(double[] p1, double[] p2) { final double A = -(p2[1]-p1[1]); // -(y2-y1) final double B = (p2[0]-p1[0]); // (x2-x1) final double C = -p1[1]*p2[0] + p1[0]*p2[1]; // -y1x2 + x1y2 final double k = (p2[1]-p1[1])/(p2[0]-p1[0]); // (y2-y1)/(x2-x1) final double b = (p1[1]*p2[0]-p1[0]*p2[1])/(p2[0]-p1[0]); // (y1x2-x1y2)/(x2-x1) return new LineFunction() { @Override public double value(double x) { return k*(double)x + b; } @Override public double getA() {return A;} @Override public double getB() {return B;} @Override public double getC() {return C;} @Override public double getk() {return k;} @Override public double getb() {return b;} }; } /** * Returns perpendicular line function of given segment. * @param p1 - first point of segment. * @param p2 - second point of segment. * @return line function of given segment. * @tested */ public static LineFunction getNormalLineFunction(double[] p1, double[] p2, double[] pM) { final double k = -(p2[0]-p1[0])/(p2[1]-p1[1]); // -(x2-x1)/(y2-y1) final double b = pM[1]+(-k)*pM[0]; // y0+(x2-x1)/(y2-y1)*x0 final double A = k; final double B = -1; final double C = b; return new LineFunction() { @Override public double value(double x) { return k*(double)x + b; } @Override public double getA() {return A;} @Override public double getB() {return B;} @Override public double getC() {return C;} @Override public double getk() {return k;} @Override public double getb() {return b;} }; } /** * Returns middle normal line function of given segment. * @param p1 - first point of segment. * @param p2 - second point of segment. * @return middle normal line function of given segment. * @tested */ public static LineFunction getMiddleNormalLineFunction(double[] p1, double[] p2) { // Middle point double xMdl = (p1[0]+p2[0])/2.0; double yMdl = (p1[1]+p2[1])/2.0; final double k = -(p2[0]-p1[0])/(p2[1]-p1[1]); // -(x2-x1)/(y2-y1) final double b = yMdl+(-k)*xMdl; // y0+(x2-x1)/(y2-y1)*x0 final double A = k; final double B = -1; final double C = b; return new LineFunction() { @Override public double value(double x) { return k*(double)x + b; } @Override public double getA() {return A;} @Override public double getB() {return B;} @Override public double getC() {return C;} @Override public double getk() {return k;} @Override public double getb() {return b;} }; } /** * Calculates distance from point to line. * @param point - given point. * @param func - function of line. * @return distance from point to line. * @tested */ private static double distanceFromPointToLine(double[] point, LineFunction func) { double A = func.getA(); double B = func.getB(); double C = func.getC(); double tmp = Math.sqrt(A*A + B*B); return Math.abs(A*point[0] + B*point[1] + C) / tmp; } /** * Calculates distance from point to line. * @param point - given point. * @param line - given line. * @return distance from point to line. * @tested */ private static double distanceFromPointToLine(double[] point, double[] line) { double A = (line[3]-line[1]); double B = -(line[2]-line[0]); double C = (line[1]*line[2] - line[1]*line[0] - line[0]*line[3] + line[0]*line[1]); double tmp = Math.sqrt(A*A + B*B); if(0!=tmp) return Math.abs(A*point[0] + B*point[1] + C) / tmp; return SimpleGeometry.distance(point, new double[]{line[0], line[1]}); } }