다음 예제는 베지어 곡선을 그리는 예로 1차 곡선입니다.
즉 시작하는 점은 2개의 점이며 이를 잊는 직선으로 되있을 경우에 베지어 곡선을 그리는 결과를 나타냅니다.
초기 화면은 다음과 같습니다. 두점과 그를 잊는 직선으로 이루어진 경로가 있을 경우의 베지어 곡선입니다.
시작 버튼을 누르게 되면 베지어 곡선을 그리게 되며, 시작 버튼을 누리기 전에 점을 클릭해서 드래그 하면
점의 위치를 변경할수 있읍니다.
다음은 소스 입니다.
Option Explicit ' 모든 변수는 선언된 뒤에 사용 할 수 있다.
Option Base 1
Private Const XPoint = 1
Private Const YPoint = 2
Private HarfDot As Long ' 점의 반지름
Private Pointer() As Long ' 현재 점의 위치
Private Dimension() As Long ' 각 차수 시작 첨자
Private SelectDot As Long ' 현재 마우스로 선택된 점의 인덱스 번호
Private Sub CreatePoint(ByVal index As Long) ' 점을 생성한다.
Pointer(XPoint, index) = Rnd(1) * picClient.Width
Pointer(YPoint, index) = Rnd(1) * picClient.Height
End Sub
Private Function GetDimension(ByVal index As Long) As Long ' 점의 어떤 차원의 점인지를 얻는다
For GetDimension = UBound(Dimension) To 1 Step -1
If index >= Dimension(GetDimension) Then Exit For
Next GetDimension
End Function
Private Sub DisplayPoint(ByVal index As Long) ' 점을 표시한다.
Dim LoadConffirm As Boolean
On Error Resume Next
LoadConffirm = shpPoint(index).Visible
If Err.Number > 0 Then Load shpPoint(index)
On Error GoTo 0
With shpPoint(index)
.BackColor = QBColor(GetDimension(index))
.Left = Pointer(XPoint, index) - HarfDot
.Top = Pointer(YPoint, index) - HarfDot
.Visible = True
End With
End Sub
Private Sub DrawLine(ByVal index As Long, ByVal Befor As Boolean, ByVal Clear As Boolean) ' 점과 점을 잊는 선을 그린다.
Dim x2 As Long ' 연결할 점의 좌표
Dim y2 As Long
Dim C As Long ' 연결할 선의 색
x2 = Pointer(XPoint, index + IIf(Befor, -1, 1)) ' 연결할 점의 좌표를 얻는다.
y2 = Pointer(YPoint, index + IIf(Befor, -1, 1))
picClient.Line (Pointer(XPoint, index), Pointer(YPoint, index))-(x2, y2), IIf(Clear, picClient.BackColor, QBColor(GetDimension(index)))
End Sub
Private Function CursorInDot(ByVal x As Long, ByVal y As Long) As Long ' 커서가
For CursorInDot = UBound(Pointer, 1) To 1 Step -1
If Pointer(XPoint, CursorInDot) - HarfDot <= x And Pointer(XPoint, CursorInDot) + HarfDot >= x And _
Pointer(YPoint, CursorInDot) - HarfDot <= y And Pointer(YPoint, CursorInDot) + HarfDot >= y Then
Exit For
End If
Next CursorInDot
End Function
Private Function GetDotNumber() As Long ' 점 수
GetDotNumber = UBound(Pointer, 2)
End Function
Private Sub cmdStart_Click() ' 시작
timProcess = True
cmdStart.Enabled = False
End Sub
Private Sub Form_Load()
Randomize ' 난수 발생기를 초기화 한다
HarfDot = shpPoint(0).Width / 2 ' 점의 반지름
ReDim Dimension(1) ' 1차원
ReDim Pointer(YPoint, 2) ' 포인터가 저장될 배열의 초기화, 초기 점 2개에 좌표(x,y)
Dimension(1) = 1 ' 1차원 포인터의 시작 첨자
picClient.AutoRedraw = True
CreatePoint 1 ' 점을 생성한다.
CreatePoint 2
DisplayPoint 1 ' 점을 표시한다.
DisplayPoint 2
DrawLine 2, True, False
End Sub
Private Sub picClient_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
If Not Button = vbLeftButton Then Exit Sub ' 왼쪽 버튼일때만 처리
SelectDot = CursorInDot(x, y) ' 선택된 점 지정
End Sub
Private Sub picClient_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
If Not Button = vbLeftButton Or SelectDot = 0 Then Exit Sub ' 왼족 버튼과, 점을 선택한경우만 처리
If Not SelectDot = UBound(Pointer, 1) Then
DrawLine SelectDot, False, True
End If
If Not SelectDot = 1 Then
DrawLine SelectDot, True, True
End If
Pointer(XPoint, SelectDot) = x
Pointer(YPoint, SelectDot) = y
DisplayPoint SelectDot
If Not SelectDot = UBound(Pointer, 1) Then
DrawLine SelectDot, False, False
End If
If Not SelectDot = 1 Then
DrawLine SelectDot, True, False
End If
End Sub
Private Sub picClient_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
SelectDot = 0
End Sub
Private Sub timProcess_Timer()
Static T As Double ' 비율
Static Bx As Long ' 이전 베지어 곡선 마지막 좌표
Static By As Long ' 이전 베지어 곡선 마지막 좌표
Dim CurrentDimension As Long ' 현재 차운
Dim ForPointerCounter As Long ' 현재 포인터 인덱스
Dim LastPointIndex As Long ' 현재 차원의 마지막 점의 인덱스-1
Dim NextDimensionDotIndex As Long ' 현재 직선에 대한 다음 차원의 점 인덱스 번호
timProcess.Enabled = False
If T >= 1 Then ' 비율 계산, 및 초기화
Exit Sub
Else
T = T + 0.01
labRateValue.Caption = Format(T, "0.00")
CurrentDimension = 1
ForPointerCounter = 1
End If
If UBound(Dimension) = CurrentDimension Then
LastPointIndex = UBound(Pointer, 1) - 1
Else
LastPointIndex = (Dimension(CurrentDimension + 1) - 1) - 1
End If
For ForPointerCounter = Dimension(CurrentDimension) To LastPointIndex
If ForPointerCounter = Dimension(CurrentDimension) And UBound(Dimension) = CurrentDimension Then
ReDim Preserve Dimension(CurrentDimension + 1)
Dimension(CurrentDimension + 1) = UBound(Pointer, 1) + 1
End If
NextDimensionDotIndex = Dimension(CurrentDimension + 1) + (ForPointerCounter - Dimension(CurrentDimension))
If UBound(Pointer, 1) < NextDimensionDotIndex Then ReDim Preserve Pointer(YPoint, NextDimensionDotIndex)
Pointer(XPoint, NextDimensionDotIndex) = Pointer(XPoint, ForPointerCounter) + (Pointer(XPoint, ForPointerCounter) - Pointer(XPoint, ForPointerCounter + 1)) * T * -1
Pointer(YPoint, NextDimensionDotIndex) = Pointer(YPoint, ForPointerCounter) + (Pointer(YPoint, ForPointerCounter) - Pointer(YPoint, ForPointerCounter + 1)) * T * -1
DisplayPoint NextDimensionDotIndex
Next
CurrentDimension = CurrentDimension + 1 ' 다음 차원
If GetDotNumber - Dimension(CurrentDimension) = 0 Then ' 이전 이벤트의 마지막 점과, 현재의 마지막 점을 연결하여 베지어 곡선을 그린다
If Bx = 0 Then
Bx = Pointer(XPoint, 1)
By = Pointer(YPoint, 1)
End If
picClient.Line (Bx, By)-(Pointer(XPoint, GetDotNumber), Pointer(YPoint, GetDotNumber)), vbRed
Bx = Pointer(XPoint, GetDotNumber)
By = Pointer(YPoint, GetDotNumber)
End If
timProcess.Enabled = True
End Sub
다음 번에는 시작점이 3개인 즉, 직선이 2개인 경로를 갖는 경우의 베지어 곡선을 그려보겠읍니다.
'VB6' 카테고리의 다른 글
DLL의 클래스의 폼에 텍스트 박스에 입력한 값을 클래스의 개체를 생성한 모듈에 전달 (0) | 2011.09.19 |
---|---|
다차원 베지어 곡선 그리기 (0) | 2011.09.19 |
vb6에서 정규식으로 문자열을 찾자. (0) | 2011.09.16 |
소수를 분수로 바꾸기 (0) | 2011.09.16 |
유니코드 한글 초성,중성,종성 분리 (0) | 2011.09.09 |