给定线段的两个端点A(x1,y1) , B(x2,y2)的坐标和点E(x,y)的坐标;任务是找到从点到以给定坐标形成的线段的最小距离。
注意,一条线的两端都可以无穷大,即一条线没有终点。另一方面,由于线段的长度是固定的,因此线段具有起点和终点。
例子:
Input: A = {0, 0}, B = {2, 0}, E = {4, 0}
Output: 2
To find the distance, dot product has to be found between vectors AB, BE and AB, AE.
AB = (x2 – x1, y2 – y1) = (2 – 0, 0 – 0) = (2, 0)
BE = (x – x2, y – y2) = (4 – 2, 0 – 0) = (2, 0)
AE = (x – x1, y – y1) = (4 – 0, 0 – 0) = (4, 0)
AB . BE = (ABx * BEx + ABy * BEy) = (2 * 2 + 0 * 0) = 4
AB . AE = (ABx * AEx + ABy * AEy) = (2 * 4 + 0 * 0) = 8
Therefore, nearest point from E to line segment is point B.
Minimum Distance = BE =
= 2
Input: A = {0, 0}, B = {2, 0}, E = {1, 1}
Output: 1
方法:想法是使用向量的概念来解决问题,因为最近的点始终位于线段上。假设矢量AB的方向是从A到B,则出现三种情况:
1.如果向量AB(A到B)和向量BE(B到E)的点积为正,则线段AB上距E点最近的点就是B点本身,其中E是给定点。自AB以来。 BE> 0时,给定点的方向与向量AB的方向相同,并且最接近的点必须为B本身,因为最接近的点位于线段上。
2.如果向量AB(A到B)和向量BE(B到E)的点积为负,则线段AB上距点E最近的点就是点A本身,其中E是给定点。自AB以来。 BE <0时,给定点位于线段AB的相反方向上,并且最近点必须为A本身,因为最近点位于线段上。
3.如果点积为0,则点E垂直于线段AB,并且距线段AB到给定点E的垂直距离是最短距离。如果某个任意点F是线段上与E垂直的点,则垂直距离可以计算为| EF |。 = |(AB X AE)/ | AB ||
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
// To store the point
#define Point pair
#define F first
#define S second
using namespace std;
// Function to return the minimum distance
// between a line segment AB and a point E
double minDistance(Point A, Point B, Point E)
{
// vector AB
pair AB;
AB.F = B.F - A.F;
AB.S = B.S - A.S;
// vector BP
pair BE;
BE.F = E.F - B.F;
BE.S = E.S - B.S;
// vector AP
pair AE;
AE.F = E.F - A.F,
AE.S = E.S - A.S;
// Variables to store dot product
double AB_BE, AB_AE;
// Calculating the dot product
AB_BE = (AB.F * BE.F + AB.S * BE.S);
AB_AE = (AB.F * AE.F + AB.S * AE.S);
// Minimum distance from
// point E to the line segment
double reqAns = 0;
// Case 1
if (AB_BE > 0) {
// Finding the magnitude
double y = E.S - B.S;
double x = E.F - B.F;
reqAns = sqrt(x * x + y * y);
}
// Case 2
else if (AB_AE < 0) {
double y = E.S - A.S;
double x = E.F - A.F;
reqAns = sqrt(x * x + y * y);
}
// Case 3
else {
// Finding the perpendicular distance
double x1 = AB.F;
double y1 = AB.S;
double x2 = AE.F;
double y2 = AE.S;
double mod = sqrt(x1 * x1 + y1 * y1);
reqAns = abs(x1 * y2 - y1 * x2) / mod;
}
return reqAns;
}
// Driver code
int main()
{
Point A = make_pair(0, 0);
Point B = make_pair(2, 0);
Point E = make_pair(1, 1);
cout << minDistance(A, B, E);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static class pair
{
double F, S;
public pair(double F, double S)
{
this.F = F;
this.S = S;
}
public pair() {
}
}
// Function to return the minimum distance
// between a line segment AB and a point E
static double minDistance(pair A, pair B, pair E)
{
// vector AB
pair AB = new pair();
AB.F = B.F - A.F;
AB.S = B.S - A.S;
// vector BP
pair BE = new pair();
BE.F = E.F - B.F;
BE.S = E.S - B.S;
// vector AP
pair AE = new pair();
AE.F = E.F - A.F;
AE.S = E.S - A.S;
// Variables to store dot product
double AB_BE, AB_AE;
// Calculating the dot product
AB_BE = (AB.F * BE.F + AB.S * BE.S);
AB_AE = (AB.F * AE.F + AB.S * AE.S);
// Minimum distance from
// point E to the line segment
double reqAns = 0;
// Case 1
if (AB_BE > 0)
{
// Finding the magnitude
double y = E.S - B.S;
double x = E.F - B.F;
reqAns = Math.sqrt(x * x + y * y);
}
// Case 2
else if (AB_AE < 0)
{
double y = E.S - A.S;
double x = E.F - A.F;
reqAns = Math.sqrt(x * x + y * y);
}
// Case 3
else
{
// Finding the perpendicular distance
double x1 = AB.F;
double y1 = AB.S;
double x2 = AE.F;
double y2 = AE.S;
double mod = Math.sqrt(x1 * x1 + y1 * y1);
reqAns = Math.abs(x1 * y2 - y1 * x2) / mod;
}
return reqAns;
}
// Driver code
public static void main(String[] args)
{
pair A = new pair(0, 0);
pair B = new pair(2, 0);
pair E = new pair(1, 1);
System.out.print((int)minDistance(A, B, E));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
from math import sqrt
# Function to return the minimum distance
# between a line segment AB and a point E
def minDistance(A, B, E) :
# vector AB
AB = [None, None];
AB[0] = B[0] - A[0];
AB[1] = B[1] - A[1];
# vector BP
BE = [None, None];
BE[0] = E[0] - B[0];
BE[1] = E[1] - B[1];
# vector AP
AE = [None, None];
AE[0] = E[0] - A[0];
AE[1] = E[1] - A[1];
# Variables to store dot product
# Calculating the dot product
AB_BE = AB[0] * BE[0] + AB[1] * BE[1];
AB_AE = AB[0] * AE[0] + AB[1] * AE[1];
# Minimum distance from
# point E to the line segment
reqAns = 0;
# Case 1
if (AB_BE > 0) :
# Finding the magnitude
y = E[1] - B[1];
x = E[0] - B[0];
reqAns = sqrt(x * x + y * y);
# Case 2
elif (AB_AE < 0) :
y = E[1] - A[1];
x = E[0] - A[0];
reqAns = sqrt(x * x + y * y);
# Case 3
else:
# Finding the perpendicular distance
x1 = AB[0];
y1 = AB[1];
x2 = AE[0];
y2 = AE[1];
mod = sqrt(x1 * x1 + y1 * y1);
reqAns = abs(x1 * y2 - y1 * x2) / mod;
return reqAns;
# Driver code
if __name__ == "__main__" :
A = [0, 0];
B = [2, 0];
E = [1, 1];
print(minDistance(A, B, E));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
class pair
{
public double F, S;
public pair(double F, double S)
{
this.F = F;
this.S = S;
}
public pair() {
}
}
// Function to return the minimum distance
// between a line segment AB and a point E
static double minDistance(pair A, pair B, pair E)
{
// vector AB
pair AB = new pair();
AB.F = B.F - A.F;
AB.S = B.S - A.S;
// vector BP
pair BE = new pair();
BE.F = E.F - B.F;
BE.S = E.S - B.S;
// vector AP
pair AE = new pair();
AE.F = E.F - A.F;
AE.S = E.S - A.S;
// Variables to store dot product
double AB_BE, AB_AE;
// Calculating the dot product
AB_BE = (AB.F * BE.F + AB.S * BE.S);
AB_AE = (AB.F * AE.F + AB.S * AE.S);
// Minimum distance from
// point E to the line segment
double reqAns = 0;
// Case 1
if (AB_BE > 0)
{
// Finding the magnitude
double y = E.S - B.S;
double x = E.F - B.F;
reqAns = Math.Sqrt(x * x + y * y);
}
// Case 2
else if (AB_AE < 0)
{
double y = E.S - A.S;
double x = E.F - A.F;
reqAns = Math.Sqrt(x * x + y * y);
}
// Case 3
else
{
// Finding the perpendicular distance
double x1 = AB.F;
double y1 = AB.S;
double x2 = AE.F;
double y2 = AE.S;
double mod = Math.Sqrt(x1 * x1 + y1 * y1);
reqAns = Math.Abs(x1 * y2 - y1 * x2) / mod;
}
return reqAns;
}
// Driver code
public static void Main(String[] args)
{
pair A = new pair(0, 0);
pair B = new pair(2, 0);
pair E = new pair(1, 1);
Console.Write((int)minDistance(A, B, E));
}
}
// This code is contributed by 29AjayKumar
1
时间复杂度: O(1)
辅助空间: O(1)