我试图从闭合曲线外的给定点(不在曲线上)找到切线。该曲线被定义为点的2D x和y坐标,例如形状像不规则的椭圆。
如果用户给出一个点:(x0,y0)=(-30,80),我怎么知道曲线上的切点(显然是平滑曲线中离散点之间的最近点)(即切线来自(x0,y0)到曲线)?
答案 0 :(得分:4)
一种可能性是使用数值微分来找到每个点处的切线,并确定它是否“足够接近”给定点。然而,人们必须认真思考“足够接近”以避免得不到匹配或太多。
这是另一种方法:考虑从给定点(x0,y0)指向曲线上的点的单位向量。找到它们之间的最大差距(命令convhull在这里有帮助)。间隙两侧的矢量确定切线。
一般来说,这只会找到两条切线,而不是全部切线。但如果曲线是凸的,那么无论如何只有两条切线。
这是一个棘手情况的例子,其中给定点位于曲线的凸包内。
产生上述图片的代码:
var routines = [NSManagedObject]()
override func viewWillAppear(animated: Bool) {
self.navigationItem.leftBarButtonItem = self.editButtonItem()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
let fetchRequest = NSFetchRequest(entityName: "Routine")
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
if let results = fetchedResults {
routines = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
另一种方法,如果(x0,y0)不在曲线的凸包内,则可以正常工作。
使用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
查找曲线和给定点convhull
的并集的凸包。凸出船体的两个入射到(x0,y0)
的边缘与曲线相切:
产生上述图片的代码:
(x0,y0)