简体   繁体   English

从曲线外的用户给定点查找曲线上的切点

[英]Find tangent points on a curve from a user-given point outside the curve

I am trying to find the tangent lines from a given point outside a closed curve (not on the curve). 我正在尝试从封闭曲线(不在曲线上)之外的给定点查找切线。 The curve is defined as 2D x and y coordinates of points,shaped like an irregular ellipse for example. 曲线定义为点的2D x和y坐标,例如形状像不规则椭圆。

If given a point by the user: (x0,y0) = (-30,80), how can I know the tangent points (obviously closest point among discrete points from the smooth curve) on curve (ie tangent lines from (x0,y0) to curve)? 如果用户给定一个点:(x0,y0)=(-30,80),我怎么能知道曲线上的切点(显然是平滑曲线的离散点中最接近的点)(即,(x0, y0)曲线)?

One possibility is to use numerical differentiation to find the tangent line at every point, and decide whether it passes "close enough" to the given point. 一种可能的方法是使用数值微分法在每个点处找到切线,然后确定切线是否“足够接近”通过给定点。 However, one has to think hard about "close enough" to avoid getting either no matches or too many. 但是,必须认真考虑“足够接近”,以免得不到任何匹配或太多匹配。

Here is another approach: consider the unit vectors pointing from the given point (x0,y0) to the points on the curve. 这是另一种方法:考虑从给定点(x0,y0)指向曲线上的点的单位向量。 Find the largest gap between them (the command convhull helps here). 找到它们之间的最大缝隙(命令convhull在这里有帮助)。 The vectors on both sides of the gap determine tangent lines. 间隙两侧的向量确定切线。

In general this will find only two tangent lines, not all of them. 通常,这只会找到两条切线,而不是全部。 But if the curve is convex, there are only two tangent lines anyway. 但是,如果曲线是凸的,则无论如何只有两条切线。

Here is an example of the tricky situations where the given point is within the convex hull of the curve. 这是给定点在曲线的凸包内的棘手情况的示例。

狡猾

The code that produced the above picture: 产生上图的代码:

t = linspace(0,2*pi,100);
x = 10*cos(t) + sin(7*t);
y = 6*sin(t) + cos(13*t);                 % x,y  describe the curve; 

x0 = 4; y0 = 5;                           % given point 

xn = (x-x0)./sqrt((x-x0).^2+(y-y0).^2);   % unit vectors 
yn = (y-y0)./sqrt((x-x0).^2+(y-y0).^2);   % from x0,y0 to points on the curve
cvx = convhull(xn,yn);                    % convex hull of unit vectors  

[~,i] = max(diff(xn(cvx)).^2+diff(yn(cvx)).^2);    % largest gap in the hull
x1 = xn(cvx(i)); y1=yn(cvx(i));            % vectors on both sides
x2 = xn(cvx(i+1)); y2=yn(cvx(i+1));        % of the gap     

plot(x,y)
hold on
s = linspace(0,10);
plot(x0+s*x1, y0+s*y1, 'r')                % output
plot(x0+s*x2, y0+s*y2, 'r') 
hold off

Another approach , which works fine if (x0,y0) is not within the convex hull of the curve. 另一种方法 ,如果(x0,y0)不在曲线的凸包内,则该方法很好用。

Use convhull to find the convex hull of the union of the curve and of the given points (x0,y0) . 使用convhull查找曲线和给定点(x0,y0)并集的凸包。 The two edges of the convex hull that are incident to (x0,y0) are tangent to the curve: 凸包的入射到(x0,y0)的两个边与曲线相切:

凸包

The code that produced the above picture: 产生上图的代码:

t = linspace(0,2*pi,100);
x = 10*cos(t) + sin(7*t);
y = 6*sin(t) + cos(13*t);                 % x,y  describe the curve; 

x0 = 4; y0 = 8;                           % given point 

xe = [x0, x]; ye = [y0, y];               % put all points together 
cvx = convhull(xe,ye);                    % find convex hull 

x1 = xe(cvx(2)); y1=ye(cvx(2));           % one neighbor of (x0,y0)
x2 = xe(cvx(end-1)); y2=ye(cvx(end-1));   % another neighbor

plot(x,y)
hold on
s = linspace(0,2);
plot(x0+s*(x1-x0), y0+s*(y1-y0), 'r')     % plot the lines 
plot(x0+s*(x2-x0), y0+s*(y2-y0), 'r') 
hold off

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM