您不应该以像素为单位进行思考。坐标是浮点值。 (x,y) 处的几何点根本不需要是像素。实际上,您应该将像素视为坐标系中的矩形。
这意味着“终点之前的 x 个像素”实际上没有意义。如果像素是矩形,则水平移动时的“x 像素”与垂直移动时的数量不同。如果你朝任何其他方向移动,就更难确定它的含义了。
根据您要执行的操作,用像素术语翻译您的概念可能容易,也可能不容易。然而,相反的做法可能会更好,停止以像素为单位进行思考,将您当前以像素表示的所有内容都转换为非像素术语。
还请记住,像素究竟是什么取决于系统,通常,您可能会也可能不会查询系统(特别是如果您考虑到诸如视网膜显示器和所有分辨率无关的功能)。
编辑:
我看到你编辑了你的问题,但“点”并不比“像素”更精确。
不过,我会尽力为您提供一个可行的解决方案。至少,一旦您以正确的方式重新表述您的问题,它就会是可行的。
你的问题,正确表述,应该是:
给定笛卡尔空间中的两个点A 和B 和距离delta,点C 的坐标是多少,使得C 在通过@987654327 的线上@和B,段BC的长度是delta?
以下是该问题的解决方案:
// Assuming point A has coordinates (x,y) and point B has coordinates (p,q).
// Also assuming the distance from B to C is delta. We want to find the
// coordinates of C.
// I'll rename the coordinates for legibility.
double ax = x;
double ay = y;
double bx = p;
double by = q;
// this is what we want to find
double cx, cy;
// we need to establish a limit to acceptable computational precision
double epsilon = 0.000001;
if ( bx - ax < epsilon && by - ay < epsilon ) {
// the two points are too close to compute a reliable result
// this is an error condition. handle the error here (throw
// an exception or whatever).
} else {
// compute the vector from B to A and its length
double bax = bx - ax;
double bay = by - ay;
double balen = sqrt( pow(bax, 2) + pow(bay, 2) );
// compute the vector from B to C (same direction of the vector from
// B to A but with lenght delta)
double bcx = bax * delta / balen;
double bcy = bay * delta / balen;
// and now add that vector to the vector OB (with O being the origin)
// to find the solution
cx = bx + bcx;
cy = by + bcy;
}
您需要确保 A 点和 B 点不太接近,否则计算会不精确,结果会与您预期的不同。这就是epsilon 应该做的事情(你可能想也可能不想改变epsilon 的值)。
理想情况下,epsilon 的合适值与double 中可表示的最小数字无关,而是与double 为您提供的坐标数量级值的精度级别相关。
我已经硬编码了epsilon,这是定义它的值的常用方法,因为您通常事先知道数据的数量级,但也有“自适应”技术可以从实际计算epsilon参数的值(在本例中为 A 和 B 的坐标以及增量)。
还请注意,我已经为易读性进行了编码(编译器应该能够进行优化)。如果您愿意,请随时重新编码。