아래는 이미지의 예입니다. 중간에 흰색 점이 있고 모든 빨간색 원이 이미 존재하는 경우 파란색 원에 대해 가장 가까운 위치를 찾고 싶습니다 (명확한 위치에 있음). . 그 위치를 어떻게 찾을 수 있습니까?
나를위한 성능은이 응용 프로그램의 주요 관심사가 아닙니다.
아래는 이미지의 예입니다. 중간에 흰색 점이 있고 모든 빨간색 원이 이미 존재하는 경우 파란색 원에 대해 가장 가까운 위치를 찾고 싶습니다 (명확한 위치에 있음). . 그 위치를 어떻게 찾을 수 있습니까?
나를위한 성능은이 응용 프로그램의 주요 관심사가 아닙니다.
답변:
파란색 원의 위치에 흰색 점까지의 최단 거리를 제공하지 않는 경우가 많았 기 때문에 일반적인 해결책은 아닙니다. 예를 들어, 100 개의 빨간 공이 함께 그룹화되어 있고 흰색 점이이 빨간 공 그룹에서 멀리 떨어져 있으면, 빨간 공 중 어느 것도 파란 점의 위치에 영향을 미치지 않을 것입니다. . 모든 계산 세부 사항도 표시하지 않습니다. 어쨌든 솔루션 (파란색 원)이 두 개의 빨간색 원에 접하는 구성의 하위 집합의 경우 다음이 작동해야합니다
.1) R이 파란색 원의 반경이되게하십시오
.2) 모든 빨간색 원 쌍을 반복합니다. 나는 이것이 O (n2)라는 것을 알고 있습니다.
3) 각각의 반경 ri 및 rj를 갖는 (xi, yi) 및 (xj, yj)에 중심을 갖는 각 원 쌍 i, j에 대해, 원 쌍 사이의 거리의 제곱을 계산
d_ij^2=(xi-xj)^2+(yi-yj)^2
4) 모든 원을
dij^2<R^2
목록으로.
5)리스트를 순회하면서 i와 j 서클에 반지름 R 탄젠트의 2 개 솔루션을 찾습니다. 이렇게하려면이 방정식을이 이미지와 함께 사용하십시오
a = R+ri
b = R+rj
c = dij
α = arccos((b^2+c^2-a^2)/(2bc)
위의 정보를 통해 i 및 j 원에 접하는 두 원의 중심 (X1ij, Y1ij) 및 (X2ij, Y2ij)를 찾을 수 있습니다. 각 후보 파란색 원에 대해 다른 모든 빨간색 원을 반복하고 겹치지 않는지 확인하십시오. 그들이 흰색 원까지의 거리를 확인하지 않으면 그것을 폐기하는 경우. 더 작은 거리를 유지하면 원 쌍 목록을 순회 할 때 해결책이 있다고 생각합니다. 알고리즘은 O (n3)처럼 보입니다.
점에 가장 가까운 배치는 점 위에 있거나 원을 터치합니다.
따라서 먼저 점을 확인한 다음 기존의 각 원의 가장자리 주위에 새 원을 굴려 점에서 거리를 계산하고 갈 때 겹치는 경우 최소 거리 지점을 추적하십시오. 모든 원을 통과했을 때 중지하십시오.
즉. 녹색 선의 모든 점과 흰색 원을 확인하십시오. 녹색 선은 빨간색과 파란색의 반지름을 가진 원입니다.
이러한 모서리를 덮을 수 있도록 교차점뿐만 아니라 녹색 선 전체를 확인해야합니다.
분명히 순회의 단계 크기는 성능 측면에서 중요합니다. 그러나 성능이 문제가되지 않음을 나타내므로 출력 값의 해상도에 해당하는 값을 선택하십시오. 즉 플로트, 긴?
설명:
내 제안은 각 원 주위의 모든 지점 을 각 지점의 다른 모든 원 과 겹치도록 테스트하는 것입니다 . 영리하지 않습니다.
그림의 예가 원의 수와 해상도를 나타내는 경우 표준 PC에서는 문제가되지 않습니다.
약 20 * 2 π * 200 포인트 * 20 교차 테스트 = 4800000 반복을 위해 평균 반경 200의 20 개의 원이 있습니다.
노트 :
이와 같은 반복적 인 접근 방식은 스텝 크기,이 경우 출력 해상도가 결과에 크게 영향을 줄 수 있다는 점에서 결함이 있습니다.
두 개의 빨간색 원이 2 픽셀 떨어져 있고 1 픽셀 반경의 파란색 원이 그 사이를 쥐고 있다고 가정 해보십시오. 파란색 원의 중심으로 두 픽셀 중 하나를 분명히 사용하면 빨간색 중 하나와 겹칩니다. 그러나 중심이 두 픽셀 사이에 있다면 원을위한 공간이 있습니다.
따라서 출력의 해상도에 대해 묻는 내 의견. 당신이 말한 것은 무엇이든 될 수 있습니다.
파란색 원의 반지름만큼 반지름이 증가한 각 원 쌍에 대한 연립 방정식을 풀 수도 있습니다.
이렇게하면 파란색 원이 반복보다 두 개의 빨간색 원에 더 정확하게 닿는 지점이 생깁니다.
하나. 이 작업 만 수행하면 잘못되거나 응답이없는 몇 가지 조건이 있습니다. 즉.
1 개 또는 서클 없음
2 개 이상의 원이지만 목표 지점이 멀리 있고 바깥에 있습니다.
많은 원이지만 목표 지점이 표면에 가깝습니다.
이 plunk 에는 작업 코드가 포함되어 있습니다.
개념
주어진 원은 C1, C2 .... Cn
원 Cn의 좌표는 Cnx, Cny, 반지름은 Cr
필요한 원의 반지름은 R
파란색 원이 X, Y 위치에 있고 다른 원과 충돌하지 않으면 다음 방정식이 참입니다.
(C1x - X)^2 + (C1y - Y)^2 > (C1r + R)^2
(C2x - X)^2 + (C2y - Y)^2 > (C2r + R)^2
....
(Cnx - X)^2 + (Cny - Y)^2 > (Cnr + R)^2
첫 번째 방정식을 바꾸고
C1x^2 - 2C1x*X + X^2 + C1y^2 - 2C1y*Y + Y^2 > C1r^2 + 2C1r*R + R^2
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
방정식을 다음과 같이 다시 쓸 수 있습니다.
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
X^2 + Y^2 - 2C2x*X - 2C2y*Y > C2r^2 + 2C2r*R + R^2 - C2x^2 - C2y^2
....
X^2 + Y^2 - 2Cnx*X - 2Cny*Y > Cnr^2 + 2Cnr*R + R^2 - Cnx^2 - Cny^2
이행
흰색 점 (Xw, Yw)의 좌표에서 시작
var isValidLocation = function(x,y,r){
var valid = true;
for (var i = 0; i< circles.length; i++){
var circle = circles[i];
valid = valid && ((x*x + y*y - 2*circle.x*x - 2*circle.y*y) > (circle.radius*circle.radius + 2*circle.radius*r + r*r - circle.x*circle.x - circle.y*circle.y));
}
return valid;
};
var find = function(Xw,Yw,Rw){
var radius = 0;
while(true){
for (var x=-1 * radius ;x <= radius; x++) {
for (var y=-1 * radius;y <= radius; y++) {
if (isValidLocation(Xw + x,Yw + y, Rw)){
drawCircle(Xw + x,Yw + y,Rw,"#0000FF");
return;
}
}
}
radius++;
}
};
모든 방정식을 만족시키는 첫 번째 좌표는 파란색 원의 위치입니다.
확장 원 은 반지름이 r로 확장 된 원 중 하나입니다.
O 가 원 중심이 아닌 경우 추가 작업이 있습니다. 이제 O == C0이라고 가정하십시오.
각각의 반지름과 r 을 사용하여 C0과 모든 원의 모든 교집합 을 계산합니다. 즉, 확장 원과 확장 C0이 교차합니다. 교차점이없는 경우 찾고있는 점은 C0의 아무 곳에 나 있고, 교차점이있는 경우 각 교차점에 대해 다른 확장 된 원 안에 있는지 확인합니다 (C0과 교차 한 원으로 제한 할 수 있음). 다른 확장 원이 아닌 첫 번째 교차로를 P로 가져 가십시오. 다른 교차점이있을 수 있습니다.
확장 된 원과 C0 사이에 다른 확장 된 원 안에 있지 않은 교차점이없는 경우 모든 확장 된 원이 서로 교차하는 지점을 계산하십시오. 그런 다음 O까지의 거리 순서대로 이러한 교차점을 확인하십시오. 다시 교차점 중 하나라도 다른 확장 원 안에 있는지 여부를 확인하십시오.
당신이 이것을 상상한다면, 모든 원 주위에 파란색 원의 가능한 위치를 나타내는 선을 그리는 것을 상상해보십시오. 모든 확장 원을 합치면 파란색 원이 될 수없는 영역을 나타냅니다 . 당신이 찾고있는 지점은 그 노동 조합에없는 가장 가까운 지점입니다. C0에 솔루션이 아닌 합집합에없는 점이 있으면 C0이 완전히 덮힌 경우 P는 두 개의 다른 확장 원 사이의 교차점에 있어야하며 덮지 않은 영역에 있어야합니다. 이 조합 (즉 , 확장 된 원이 아님).
이것은 O (n ^ 2)입니다.이를 향상시킬 수있는 몇 가지 방법이 있습니다 . 그리드 쌍을 사용하여 현명한 검색의 노력을 줄일 수 있습니다. 또한 O와의 근접성에 따라 원을 정렬한다고 생각합니다. 두 개의 원은 라디오로 줄어 듭니다) 적용 범위 및 교차로 검색을위한 검색 공간을 제한하는 데 도움이됩니다.
이제 가능한 해결책 이되는 일련의 포인트가 있으며 ,이를 통해 반복하고 각각을 확인하십시오.
NB : 알고리즘의 구현이 정확하게 기술되어야한다고 말하는 것이 아닙니다. 동적 프로그래밍을 사용하거나 작동하지 않는 것이 확실한 솔루션을 건너 뛰어 성능을 향상시킬 수 있습니다.