点到直线、线段的距离

补充数学知识:

直线方程一般式 Ax + By + C = 0
点斜式 y-y1 = k(x - x1)
斜切式 y = kx +b
两点式 (y-y1)/(y2-y1) =(x-x1)/(x2-x1) x1不等于x2 y1不等于要y2
截距式 x/a + y/b = 1 a,b都不等于0

斜率,亦称“角系数”,表示一条直线相对于横坐标轴的倾斜程度。一条直线与某平面直角坐标系横坐标轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率。
表达式
k=tanα=(y2-y1)/(x2-x1)
对于一次函数y=kx+b(斜截式)k即该函数图像的斜率。
相关公式
当直线L的斜率存在时,斜截式y=kx+b 当k=0时 y=b 
当直线L的斜率存在时,点斜式y2—y1=k(X2—X1),
当直线L在两坐标轴上存在非零截距时,有截距式ax + by +c =0 
对于任意函数上任意一点,其斜率等于其切线与x轴正方向的夹角,即tanα  斜率计算:ax+by+c=0中,k=-a/b.   
直线斜率公式:k=(y2-y1)/(x2-x1)   
两条垂直相交直线的斜率相乘积为-1:k1*k2=-1


证明:已知一点(x0,y0)  到直线l Ax + By +c =0 的直线距离




PointToLineDis.java

package com.mapbar.algorithm;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

/**
 * 点到直线,线段的距离
 * 
 * @author chenlly
 * 
 */

public class PointToLineDis {

	private static GeometryFactory factory = new GeometryFactory();

	private static WKTReader reader = new WKTReader();

	// 直线方程一般式 Ax + By + C = 0;

	private double A;

	private double B;

	private double C;

	/**
	 * 求直线方程的一般式
	 * 
	 * @param point1
	 * @param point2
	 *            直线l经过的两个点
	 */
	public void lineExp(Point point1, Point point2) {
		/**
		 * 由起始点和终止点构成的直线方程一般式的系数A
		 */
		A = (point1.getY() - point2.getY())
				/ Math.sqrt(Math.pow((point1.getY() - point2.getY()), 2)
						+ Math.pow((point1.getX() - point2.getX()), 2));

		/**
		 * 由起始点和终止点构成的直线方程一般式的系数
		 */
		B = (point2.getX() - point1.getX())
				/ Math.sqrt(Math.pow((point1.getY() - point2.getY()), 2)
						+ Math.pow((point1.getX() - point2.getX()), 2));

		/**
		 * 由起始点和终止点构成的直线方程一般式的系数
		 */
		C = (point1.getX() * point2.getY() - point2.getX() * point1.getY())
				/ Math.sqrt(Math.pow((point1.getY() - point2.getY()), 2)
						+ Math.pow((point1.getX() - point2.getX()), 2));

	}

	/**
	 * 点到直线方程的距离 此公式需要证明
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public double alLine(double x, double y) {
		double d = Math.abs(A * (x) + B * (y) + C)/Math.sqrt(Math.pow(A,2)+Math.pow(B,2));
		return d;
	}

	/**
	 * 点到线段的距离 计算线段和计算点到直线的距离类似,不同Y点在包含l线段的投影可能不是线段上的点,投影可能在起点之前或者终点之后
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public double alSegmentDis(double x, double y, Point point1, Point point2) {
		double dis = 0;
		double a, b, c;
		a = lineDis(point1.getX(), point1.getY(), point2.getX(), point2.getY());// 线段的长度
		b = lineDis(point1.getX(), point1.getY(), x, y); // point1到点的距离
		c = lineDis(point2.getX(), point2.getY(), x, y);//point2到点的距离
		if (c + b == a) {// 点在线段上
			dis = 0;
			return dis;
		}
		if (c * c >= a * a + b * b) { // 组成直角三角形或钝角三角形,投影在point1延长线上,
			dis = b;
			return dis;
		}
		if (b * b >= a * a + c * c) {// 组成直角三角形或钝角三角形,投影在point2延长线上,
			dis = c;
			return dis;
		}
		// 组成锐角三角形,则求三角形的高
		double p = (a + b + c) / 2;// 半周长
		double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积
		dis = 2 * s / a;// 返回点到线的距离(利用三角形面积公式求高)
		return dis;
	}

	/**
	 * 计算两点之间的距离
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @return
	 */
	private double lineDis(double x1, double y1, double x2, double y2) {
		double lineLength = 0;
		lineLength = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
		return lineLength;
	}

	public static void main(String[] args) throws ParseException {
		PointToLineDis pl = new PointToLineDis();
		// 直线经过的两个点
		String line = "LINESTRING (-5 6, -4 8)";
		Geometry geometry = reader.read(line);
		Coordinate[] coords = geometry.getCoordinates();
		Point point1 = factory.createPoint(coords[0]);
		Point point2 = factory.createPoint(coords[1]);
		// 求直线方程一般式
		pl.lineExp(point1, point2);
		// 点(x,y)
		double x = 2;
		double y = -1;
		double d1 = pl.alLine(x, y);
		System.out.println("result:" + d1);// result:9.391485505499116

		double x1 = -3;
		double y1 = 3;
		double d2 = pl.alSegmentDis(x1, y1, point1, point2);
		System.out.println("result:" + d2);// result:3.605551275463989

	}
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值