각 도형의 외곽선과, 내부 선의 교차점을 찾아내 첫 도형의 교차점에서 시작해 다음 도형의 교차점에서 종료되는 코드를 만들고 싶었고, 해당 교차점을 찾아내는 것이 의외로 수학의 기하학이라는 수학을 활용해야 하는 복잡한 연산임을 깨닫고, 이런 저런 검색을 하게되었다.
두 직선의 교차점을 찾는 방법을 프로그래밍 코드화 하기 위해 제타위키 에서 나온 교차점 공식을 적용 한 코드를 작성하게 되었다.
두 직선의 교차점 - 제타위키
도형에는 외곽선이 하나가 아닌 여러개이기에,
해당 선분을 빼내어 배열에 넣고 해당 배열의 각 변의 시작점과 종로점의 x축, y축을
각각 (x1, y1, x2, y2)로 입력하였다.
또한 교차를 검사할 대상의 경우 단 하나의 선이므로, 해당 선의 좌표는 x1, y1, x2, y2로 이루어진 하나의 선이다.
/**
* 기하학 공식 대입 도형의 외곽선과 라인의 크로스포인트를 찾는 역할
* @param ob1 크로스 포인트를 찾을 도형의 선 집합
* @param ob2 크로스포인트를 찾을 선
* @returns
*/
- function findCrossPoint(sr, tr){
- var pos = [];
- for(var i = 0; i < sr.length; i++){
- var tmp = sr[i];
- var p1 = (tmp.x1 - tmp.x2)*(tr.y1 - tr.y2) - (tmp.y1-tmp.y2)*(tr.x1-tr.x2);//분모로 사용됨
- // p1 ==0 이면 평행선 또는 일치 이므로 제외(분모)
- if(p1 != 0){
- var x = 0;
- var y = 0;
- var x = (((tmp.x1 * tmp.y2) - (tmp.y1 * tmp.x2))*(tr.x1 - tr.x2)
- - (tmp.x1 - tmp.x2) * ((tr.x1 * tr.y2) - (tr.y1 * tr.x2))) / p1;
- var y = (((tmp.x1 * tmp.y2) - (tmp.y1 * tmp.x2))*(tr.y1 - tr.y2)
- - (tmp.y1 - tmp.y2)*((tr.x1 * tr.y2) - (tr.y1 * tr.x2))) / p1;
- if((x - tmp.x1) * (x - tmp.x2) <= 0 && (y - tmp.y1) * (y - tmp.y2) <= 0 //교점이 1선분 위에 있고
- && (x - tr.x1) * (x - tr.x2) <= 0 && (y - tr.y1) * (y - tr.y2) <= 0 //교점이 2선분 위에 있을경우
- ){
- pos.push({ x : x , y : y }) ;
- }
- }
- }
- return pos;
- }
위에서 if문을 통해서 선분 교점의 위치가 음수나 0보다 작거나 같다는 검증을 하는 이유는 선의 전체 거리가 아닌 확장되는 축의 방향을 기준으로 교점을 검사하기에 경우에 따라서 선분이 더 확장될경우 생성되는 교점마저 추출되기 때문이다.
또한 배열에 좌표값을 넣어서 반환하는 이유는, 하나의 선이 두개 이상의 도형 선을 교차하여 통과하는 일이 발생할 수 있기 때문이다. 선하나 제대로 긋겠다고 기하학을 사용하게 될줄은... ㅎㅎ; 고딩떄 수학을 안한것이 새삼 후회하게 된다.
댓글 없음:
댓글 쓰기