我正在寻找一种方法来沿矩形的一部分周长分布点。这些点必须均匀地彼此远离。
我有一个矩形(通常是正方形)边界,沿该边界有2个点(ps
和pe
),这些点标记了允许的点范围。在这里,我用红色标记了允许的范围:
我需要n
沿着该线段放置点(通常是1-3)。这些点需要均匀隔开一定距离d
。所以n0
..n1
和n1
..n2
等之间的距离应该全部是d
。边界点也出于分配目的而计数,因此第一个点与最后一个点之间的距离和ps
/也pe
应d
同样。
这似乎是一项简单的任务,但是我很快意识到,幼稚的方法在这里行不通。取线段的长度并除以n
+1并不算在拐角处。例如:n
= 1,则使点过于接近pe
:
我的数学很生锈(日常工作通常不需要很多),但是我尝试了几种不同的方法,但都没有完全解决。我能够解决n
= 1使用载体,通过找到之间的中点ps
和pe
,找到一个垂直矢量,然后相交,与该段,如下面。我n
什至不知道如何使这种方法行之有效,即使还有其他事情,甚至可以做到。
最后一点,如果不可能实现完全均匀的分布,则可以采用足够好的近似值。理想情况下,在整个范围内,近似值的偏移量大致相同(而不是在边缘处更差)。
I am going to suggest an algorithm, but since the derivation is a bit mathematically messy, I did not have enough time to think it through carefully and to check it carefully for correctness. Plus I might have included some redundant checks, which if one proves some proper inequalities may become redundant and one may prove the existence of a solution may always exist under reasonable assumptions. I believe the idea is correct, but I might have made some mistakes writing this thing up, so be careful.
Because according to your comment, having only one corner inside the segment along the boundary of the square is enough to solve the rest of the cases due to symmetry, I will focus on the one corner case.
Your polygonal segment with one 90 degree corner is divided into a pair of perpendicular straight line segments, the first one of length l1
and the second of length l2
. These two lengths are given to you. You also want to add on the polygonal segment, which is of total length l1 + l2
, a given number of n
points so that the euclidean straight line distance between any two consecutive points is the same. Call that unknown distance d
. When you do that you are going to end up with n1
full segments of unknown length d
on l1
and n2
full segments of unknown length d
on l2
so that
n1 + n2 = n
In general, you will also end up with an extra segment of length d1 <= d
on l1
with one end at the 90 degree corner. Analogously, you will also have an extra segment of length d2 <= d
on l2
with one end at the 90 degree corner. Thus, the two segments d1
and d2
share a common end and are perpendicular, so they form a right-angled triangle. According to Pythagoras' theorem, these two segments satisfy the equation
d1^2 + d2^2 = d^2
If we combine all the equations and information up to now, we obtain a system of equations and restrictions which are:
n1*d + d1 = l1
n2*d + d2 = l2
d1^2 + d2^2 = d^2
n1 + n2 = n
n1 and n2 are non-negative integers
where the variables d, d1, d2, n1, n2
are unknown while l1, l2, n
are given. From the first two equations, you can express d1
and d2
and substitute in the third equation:
d1 = l1 - n1*d
d2 = l2 - n2*d
(l1 - n1*d)^2 + (l2 - n2*d)^2 = d^2
n1 + n2 = n
n1 and n2 are non-negative integers
In the special case, when one wants to add only one point, i.e. n = 1
, one has either n1 = n = 1
or n2 = n = 1
depending on whether l1 > l2
or l1 <= l2
respectively. Say l1 > l2
. Then n1 = n = 1
and n2 = 0
so
d1 = l1 - d
d2 = l2
(l1 - d)^2 + l2^2 = d^2
Expand the equation, simplify it and solve for d
:
l1^2 - 2*l1*d + d^2 + l2^2 = d^2
l1^2 + l2^2 - 2*l1*d = 0
d = (l1^2 + l2^2) / (2*l1)
Next, let us go back to the general case. You have to solve the system
(l1 - n1*d)^2 + (l2 - n2*d)^2 = d^2
n1 + n2 = n
n1 and n2 are non-negative integers
where the variables d, n1, n2
are unknown while l1, l2, n
are given. Expand the first equation:
l1^2 - 2 * l1 * n1 * d + n1^2 * d^2 + l2^2 - 2 * l2 * n2 * d + n2^2 * d^2 = d^2
n1 + n2 = n
n1 and n2 are non-negative integers
and group the terms together
(n1^2 + n2^2 - 1) * d^2 - 2 * (l1*n1 + l2*n2) * d + (l1^2 + l2^2) = 0
n1 + n2 = n
n1 and n2 are non-negative integers
The first equation is a quadratic equation in d
(n1^2 + n2^2 - 1) * d^2 - 2 * (l1*n1 + l2*n2) * d + (l1^2 + l2^2) = 0
By the quadratic formula you expect two solutions (in general, you choose whichever is positive. If both are positive and d < l1
and d < l2
, you may have two solutions):
d = ( (l1*n1 + l2*n2) +- sqrt( (l1*n1 + l2*n2)^2 - (l1^2 + l2^2)*(n1^2 + n2^2 - 1) ) ) / (n1^2 + n2^2 - 1)
n1 + n2 = n
n1 and n2 are non-negative integers
现在,如果您可以找到合适的n1
和n2
,则可以d
使用上面的二次公式来计算必要的值。为了存在解,平方根中的表达式必须为非负,因此您有不等式约束
d = ( (l1*n1 + l2*n2) +- sqrt( (l1*n1 + l2*n2)^2 - (l1^2 + l2^2)*(n1^2 + n2^2 - 1) ) ) / (n1^2 + n2^2 - 1)
(l1*n1 + l2*n2)^2 - (l1^2 + l2^2)*(n1^2 + n2^2 - 1) >= 0
n1 + n2 = n
n1 and n2 are non-negative integers
简化不平等表达:
(l1*n1 + l2*n2)^2 - (l1^2 + l2^2)*(n1^2 + n2^2 - 1) = (l1^2 + l2^2) - (l1*n2 - l2*n1)^2
这将我们带入以下系统
d = ( (l1*n1 + l2*n2) +- sqrt( (l1^2 + l2^2) - (l1*n2 - l2*n1)^2 ) ) / (n1^2 + n2^2 - 1)
(l1^2 + l2^2) - (l1*n2 - l2*n1)^2 >= 0
n1 + n2 = n
n1 and n2 are non-negative integers
分解不平等因素,
d = ( (l1*n1 + l2*n2) +- sqrt( (l1^2 + l2^2) - (l1*n2 - l2*n1)^2 ) ) / (n1^2 + n2^2 - 1)
(sqrt(l1^2 + l2^2) - l1*n2 + l2*n1) * (sqrt(l1^2 + l2^2) + l1*n2 - l2*n1) >= 0
n1 + n2 = n
n1 and n2 are non-negative integers
因此,对于这些限制,您有两种情况:
情况1:
d = ( (l1*n1 + l2*n2) +- sqrt( (l1^2 + l2^2) - (l1*n2 - l2*n1)^2 ) ) / (n1^2 + n2^2 - 1)
sqrt(l1^2 + l2^2) - l1*n2 + l2*n1 >= 0
sqrt(l1^2 + l2^2) + l1*n2 - l2*n1 >= 0
n1 + n2 = n
n1 and n2 are positive integers
或情况2:
d = ( (l1*n1 + l2*n2) +- sqrt( (l1^2 + l2^2) - (l1*n2 - l2*n1)^2 ) ) / (n1^2 + n2^2 - 1)
sqrt(l1^2 + l2^2) - l1*n2 + l2*n1 <= 0
sqrt(l1^2 + l2^2) + l1*n2 - l2*n1 <= 0
n1 + n2 = n
n1 and n2 are positive integers
我们关注案例1,发现案例2是不可能的。从表达开始n2 = n - n1
,然后将其替换为两个不等式中的每一个,并n1
在每个不等式的一侧进行隔离。此过程将产生:
情况1:
d = ( (l1*n1 + l2*n2) +- sqrt( (l1^2 + l2^2) - (l1*n2 - l2*n1)^2 ) ) / (n1^2 + n2^2 - 1)
( l1*n - sqrt(l1^2 + l2^2) ) / (l1 + l2) <= n1 <= ( l1*n + sqrt(l1^2 + l2^2) ) / (l1 + l2)
n1 + n2 = n
n1 and n2 are positive integers
可以看到情况2逆转了不等式,这是不可能的,因为左侧小于右侧。
所以算法可能是这样的:
function d = find_d(l1, l2, n)
{
if n = 1 and l1 > l2 {
return d = (l1^2 + l2^2) / (2*l1)
} else if n = 1 and l1 <= l2 {
return d = (l1^2 + l2^2) / (2*l2)
}
for integer n1 >= 0 starting from floor( ( l1*n - sqrt(l1^2 + l2^2) ) / (l1 + l2) ) to floor( ( l1*n + sqrt(l1^2 + l2^2) ) / (l1 + l2) ) + 1
{
n2 = n - n1
D = (l1^2 + l2^2) - (l1*n2 - l2*n1)^2
if D >= 0
{
d1 = ( (l1*n1 + l2*n2) - sqrt( D ) ) / (n1^2 + n2^2 - 1)
d2 = ( (l1*n1 + l2*n2) + sqrt( D ) ) / (n1^2 + n2^2 - 1)
if 0 < d1 < max(l1, l2) {
return d1
} else if 0 < d2 < max(l1, l2) {
return d2
} else {
return "could not find a solution"
}
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句