제목이 곧 내용.
▷전체글보기
- www.tibyte.kr 열리다! 2010.11.20 6
- 2010년 12월에 엽니다. 2010.09.19 4
- 신사고 씽넘버 드립니다(완료) 2010.08.04 3
- 블로그 일시 휴면 알림 2010.05.11 11
- 동음이의어와 다의어의 차이 2010.02.21 3
- 변수 값 범위를 제한하는 방법 2010.02.19 7
- 윈도우즈 창 닫기 2010.02.19
- 달의 위상(모양) 변화 2010.02.09 4
- 티스토리 카테고리 꾸미기? 2010.02.09
- 선분과 선분의 충돌체크 - 1 2010.01.25 10
www.tibyte.kr 열리다!
2010. 11. 20. 15:15
2010년 12월에 엽니다.
2010. 9. 19. 00:34
적은 양이지만 그동안 포스팅했던 게시물들을 그때까지 비공개 처리합니다.
2010년 12월을 기다려주세요!
* * * *
결국 11월에 열었습니다
신사고 씽넘버 드립니다(완료)
2010. 8. 4. 17:01
끝났습니다.
블로그 일시 휴면 알림
2010. 5. 11. 01:14
2011년 11월 20일까지 블로그 휴면기간입니다.
휴면기간에는 포스팅을 하지 않거나 간단한 글만 올리도록 하겠습니다.
동음이의어와 다의어의 차이
2010. 2. 21. 01:06
동음이의어(同音異義語) 와 다의어(多義語)를 사전에서 찾아보면
동음의이어 : 소리는 같으나 뜻이 다른 낱말이라고 나와 있지만 둘을 구분하긴 약간 어렵다.
다의어 : 두 가지 이상의 뜻을 가진 단어
이럴 때는 국어사전을 찾아보면 좋다.
예를 들어 '배' 라는 단어를 찾아 보면
배¹ 배² 배³ 과 같이 나타다 있는 것이 보이는데 이것들이 각각 동음이의어다.
배¹ 의 세부항목을 보면
① 척추동물의.........이렇게 원 속의 숫자로 다시 항목이 나뉘어져 있는데 이렇게 단어 하나에 여러개의 내부 항목들이 있는 것이 다의어이다.
② 물체의 중앙...
다의어는 원래의 뜻에서 여러 개의 비슷한 뜻들이 퍼져 나온 것이기 때문에 위에서 서술된 각 내부 항목들이 비슷한 것이다.
즉 복부(腹部)라는 뜻이 있는 배¹과, 선박이라는 뜻이 있는 배²는 서로 동음이의어이고
(사전에서) 다시 내부에 여러개의 하위항목이 있는 배¹은 다의어인 셈이다.
다른 예로 '가다' 라는 단어를 보면,
'배' 와는 달리 한 개의 단어만 나와 있고
세부적으로 *목적지를 향해 움직이다 , *음식의 맛이 변하다 와 같이 여러 개의 비슷한 뜻이 나와 있다.
따라서 '가다' 라는 단어는 동음이의어를 가지지 않고, 그냥 다의어인 것이다.
이번에는 '연패' 라는 단어를 보자.
연패(連敗)와 연패(連覇)라는 두 개의 단어가 나오는데
각각 "계속 패함" , "계속 우승함" 이란 뜻이다.
이런 경우 두 개의 '연패' 단어는 동음이의어 관계이지만
'연패'란 단어가 다의어인 것은 아니다.
변수 값 범위를 제한하는 방법
2010. 2. 19. 19:42
const MIN:int = 0;
const MAX:int = 400;
Math.min(Math.max(변수,MIN),MAX))
위와 같은 식을 통해 변수의 범위를 제한할 수 있습니다.
MIN값이 0이고 MAX값이 400일 때
변수가 200이면 그대로 200이고,
변수가 -100 이면 MIN값인 0,
변수가 500이면 MAX값인400이 됩니다.
어디에 활용할 수 있는지는 나중에..
윈도우즈 창 닫기
2010. 2. 19. 18:43
윈도(XP)에서 창을 열었을 때 좌측 상단의 아이콘을 클릭하면
창이 닫히네요!
달의 위상(모양) 변화
2010. 2. 9. 15:48
달을 드래그해서 지구주위에서 돌려보세요.
※ 저작자의 허락 없는 불펌을 금합니다..
===================================================================
코드
=======
curveTo로 원호 그리기 연구하다가 실패해서 삼각함수로 떼웠더니 많이 지저분하네요..
container.graphics.lineStyle(0,0xff0000);
container.graphics.moveTo(sim1.x,sim1.y);
container.graphics.lineTo(sim1.x+Math.cos(-1*angle)*20*markof(-1*angle), sim1.y+Math.sin(-1*angle)*20*markof(-1*angle));
container.graphics.moveTo(sim1.x,sim1.y);
container.graphics.lineTo(sim1.x+Math.cos(90/180*Math.PI*(1+markof(-1*angle)))*20, sim1.y+Math.sin(90/180*Math.PI*(1+markof(-1*angle)))*20);
container.graphics.lineStyle(0,0xff0000,0);
container.graphics.beginFill(0xffff00);
container.graphics.moveTo(sim2.x,sim2.y+20);
for(var lati:int = 90 ; lati>=-90 ; lati-=10) {
container.graphics.lineTo(sim2.x+Math.cos(lati/180*Math.PI)*Math.cos(-1*angle)*20*markof(-1*angle) , sim2.y+Math.sin(lati/180*Math.PI)*20);
}
for(var i:int = 0 ; i<=18 ; i++) {
container.graphics.lineTo(sim2.x+Math.cos((i*10-90)/180*Math.PI)*20*markof(angle) , sim2.y+Math.sin((i*10-90)/180*Math.PI)*20);
}
container.graphics.endFill();
티스토리 카테고리 꾸미기?
2010. 2. 9. 00:01
스킨-카테고리설정 페이지에서 소스보기를 하면
카테고리의 아이덴터티(?)를 알아낼 수 있다. (http://ruryca.tistory.com/70)
이걸로 상위 카테고리 볼드 같은게 되는지는 나중에 알아봐야겠다.
(이미 리스트형식으로 바꿔버리는바람에 ㅡㅡ)
선분과 선분의 충돌체크 - 1
2010. 1. 25. 22:52
※ 아래 코드는 실행해보지 않은것입니다. 동작하지 않을 수도 있습니다. |
점 2개의 좌표 정보로 표현된 선분이 2개 있을 때
충돌체크를 하는방법입니다.
퍼즐게임이나 슈팅게임, 아니면 총기를 발사하는 것을 구현할 때 유용하게 쓰일 수 있습니다.
첫번째 방법은 직선의 방정식을 이용하는 것입니다.
요약
아래와 같이 선분이 주어졌을때,
선분의 양 끝 두 점의 좌표를 알기때문에
직선의 방정식도 쉽게 나옵니다.
ax + by = c
a`x + b`y = c`
이 방정식에서 a, b, c, a`, b`, c` 만 변수에 저장해두는 형식으로
가상의(화면에 나타나지 않는) 직선이 있다고 생각하는 것입니다.
액션스크립트 geom 패키지의 Matrix 클래스를 사용하여
이원 일차방정식을 간단히 풀어낼 수 있겠죠.
즉, 위 방정식의 해가 교점의 좌표가 되는 것입니다.
여기서 중요한 것이
구하려는 게 직선교점이 아닌 선분교점이라는 것입니다.
위와 같이 직선의 교점이 선분 밖에 있으면 안되겠죠.
교점의 좌표가 두 선분의 중간값이 되는지 체크하면 됩니다.
위의 행렬연산에서
역행렬이 존재하지 않는 경우는
해가 없거나(두 직선이 평행)
해가 무수히 많거나(두 직선이 일치)
이 두가지인데요,
두 직선의 x y 계수의 비로 이를 분기할 수 있는데,
두 직선의 해가 없는경우는 물론 두 선분도 겹치치 않으니 생각할 필요 없는데,
해가 무수히 많은경우는 다릅니다.
이러한(위 그림과 같은) 경우에는 직선의 해는 (무수히)있으나
구하려는 선분의 교차여부를 본다면 교차하지 않는 경우이지요.
선분의 한 점이 다른 선분의 중간값이 되느냐 안되느냐 하는 체크를 4개의 점에 걸쳐 모두 시행하면
해결할 수 있습니다.
이 경우와 같이
두 선분이 서로 겹쳐지는 경우는 제작하는 프로그램의 상황에 따라
만나는 것으로 처리할지 아니면 만나지 않을 것으로 처리할지 달라지겠네요.
예를 들어 총쏘는 게임을 만든다면 저렇게 스쳐가는것을 무시하게 할 수도 있지만,
꼬여있는 선분을 푸는 퍼즐게임 같은경우는 교차ok로 인식을 해야겠죠.
구현
선분이 두 개 있다면
읽어들여야 할 변수는
line1_p1.x , line1_p1.y // 선분1 의 한쪽 끝 점의 x,y 좌표
line1_p2.x , line1_p2.y // 선분1 의 다른 한 쪽 끝 점의 x,y 좌표
line2_p1.x , line1_p1.y // 선분2 의 한쪽 끝 점의 x,y 좌표
line2_p2.x , line1_p2.y // 선분2 의 다른 한 쪽 끝 점의 x,y 좌표
이렇게 8개가 됩니다. line1_p1 , line1_p2 등은 선분의 양 끝 점(DisplayObject 形) 입니다.
직선의 방정식의 기본형을 살짝 변형하여
ax - by = -c
a`x - b`y = -c`
를 기본으로 삼기로 하고,
a, b, c, a` ,b` ,c` 에 해당하는 변수를 각각
line1_a, line1_b, line1_c, line2_a, line2_b, line2_c
이라고 정했습니다.
직선1의 방정식에서 x의 계수인 line1_a 의 값은
1/(line1_p2.x - line1_p1.x)
가 되는데요, 왜 그러냐면
그래프에서 x의 계수를 2배로 하면 x축 방향으로 2배 축소 되고,
1/2 배로 하면 x축 방향으로 1/2배 축소(2배 늘어남) 가 되므로
직선의 기울기를, 주어진 선분의 기울기와 맞추기 위해
선분이 x축 방향으로 늘어난 정도(line1_p2.x - line1_p1.x)의 역수를 x의 계수로 취해 준 것입니다.
line1_b 의 값은 같은이치로
1/(line1_p2.y - line1_p1.y) 가 되고,
line1_c 의 값은
지금까지 구한 계수(방정식에서 a, b에 해당)와 선분의 아무 한 점을 최초의 방정식
ax - by = -c
에 대입하면 나옵니다.
따라서 아래와 같이 프로그램할 수 있겠습니다.
line1_c = (line1_a*line1_p1.x + -1*line1_b*line1_p1.y)*-1
직선2의 계수들도 같은방법으로 구해주면 드디어
두 직선의 방정식이 나왔네요.
이제 행렬을 이용해서 해를 구해야합니다.
Matrix 클래스는 플래시8 부터 있기때문에 그 이전 버전에서는 직접 비슷하게 구현해야 합니다.(역행렬, 행렬곱 메서드 정도만)
액션스크립트 3.0 에서는 flash.geom 패키지에 Matrix 클래스가 들어있습니다.
위쪽의 수식에서
(a b )
(a` b`)
이 행렬을 matrix1 이라고 하고
(c )
(c`)
이 행렬은 matrix2라고 하면,
import flash.geom.Matrix;
var matrix1:Matrix = new Matrix(line1_a , -1*line1_b , line2_a , -1*line2_b );
var matrix2:Matrix = new Matrix(-1*line1_c , -1*line2_c );
var matrix3:Matrix = new Matrix();
이렇게 나타낼 수 있습니다
위쪽의 수식에서와 같이
매트릭스1을 역행렬로 변환하고, 매트릭스2를 곱해주면 되는데요,
matrix1.invert();
matrix3 = matrix1.concat(matrix2);
위와 같이 내장된 메서드를 이용하면 간단히 연산할 수 있습니다.
아! 역행렬이 존재하지 않는경우(ad-bc=0 의 꼴일 때)도 있으니까 위에 추가를 해줘야 합니다.
그래서 코드를 보면,
import flash.geom.Matrix;
var line1_a:Number = 1/(line1_p2.x - line1_p1.x);
var line1_b:Number = 1/(line1_p2.y - line1_p1.y);
var line1_c:Number = (line1_a*line1_p1.x + -1*line1_b*line1_p1.y)*-1;
var line2_a:Number = 1/(line2_p2.x - line2_p1.x);
var line2_b:Number = 1/(line2_p2.y - line2_p1.y);
var line2_c:Number = (line2_a*line1_p1.x + -1*line2_b*line2_p1.y)*-1;
var matrix1:Matrix = new Matrix(line1_a , line1_b*-1 , line2_a , line2_b*-1 );
var matrix2:Matrix = new Matrix(line1_c*-1 , line2_c*-1 );
var matrix3:Matrix = new Matrix();
if(matrix1.a*matrix1.d == matrix1.b*matrix1.c) { //만약 역행렬이 존재하지 않으면
if(matrix2.a/matrix2.c != matrix1.a/matrix2.c) { //만약 두 직선이(일치하지 않고)평행하면
//두 직선(선분)이 평행하므로 교차하지 않음
}
else {
// 두 직선이 일치함. 상황에 따라 추가 코딩.
}
}
else { //(위의 if의 부정을 받아)만약 역행렬이 존재하면,
matrix1.invert(); //행렬1을 역행렬화 함
matrix3 = matrix1.concat(matrix2); //행렬1과 행렬2의 행렬곱을 구해서 행렬3에 대입
}
일단 이렇게해서 두 직선의 교점의 좌표가 행렬3에 들어가게 됩니다.
위쪽의 행렬수식을 참고하면
matrix3.a 에는 교점의 x좌표가 들어가고
matrix3.c 에는 교점의 y좌표가 들어간다는 것을 알 수 있습니다.
그런데 구하려는 것은 직선의 교점이 아닌 선분의 교점입니다.
구한 (교)점이 선분에 포함되는지를 체크해야 합니다.
위쪽의 행렬수식을 참고하면
matrix3.a 에는 교점의 x좌표가 들어가고
matrix3.c 에는 교점의 y좌표가 들어간다는 것을 알 수 있습니다.
그런데 구하려는 것은 직선의 교점이 아닌 선분의 교점입니다.
구한 (교)점이 선분에 포함되는지를 체크해야 합니다.
if( Math.min(line1_p1.x,line1_p2.x) <= matrix3.a && Math.max(line1_p1.x,line1_p2.x) >= matrix3.a
Math.min(line1_p1.y,line1_p2.y) <= matrix3.b && Math.max(line1_p1.y,line1_p2.y) >= matrix3.b
&&
Math.min(line2_p1.x,line2_p2.x) <= matrix3.a && Math.max(line2_p1.x,line2_p2.x) >= matrix3.a
Math.min(line2_p1.y,line2_p2.y) <= matrix3.b && Math.max(line2_p1.y,line2_p2.y) >= matrix3.b )
{
//교차.
}
else {
//교차하지 않음.
}
(교차여부 확인하는 코드는 더 짧게 줄일 수 있지만 여기서는 쉽게 하기위해서, 교점좌표가 두 선분의 사이에 있는지
부등호를 사용하여 조건을 작성했습니다.)