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
Now, if you can find appropriate n1
and n2
, you can calculate the necessary d
using the quadratic formula above.
For solutions to exist, the expression in the square root has to be non-negative, so you have the inequality restriciton
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
Simplify the inequality espression:
(l1*n1 + l2*n2)^2 - (l1^2 + l2^2)*(n1^2 + n2^2 - 1) = (l1^2 + l2^2) - (l1*n2 - l2*n1)^2
which brings us to the following system
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
Factorizing the inequality,
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
So you have two cases for these restrictions:
Case 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
or
Case 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
we focus on case 1 and see that case 2 is not possible. Start by expressing n2 = n - n1
, then substitute it in each of the two inequalities and isolate n1
on one side of each inequality. This procedure yields:
Case1:
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
One can see that case 2 inverts the inequalities, which is impossible because the left side is less than the right one.
So the algorithm could be something like this:
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"
}
}
}
}
pe
andps
being the SE and SW corners and the allowed segment being all but the S edge. However, due to how these points are used any situation that would include more than 1 corner could probably just use a mirrored 1-corner solution. – Warmand
as a geometric distance or Mahalanobis distance? – Moussorgsky