'判断某点是否有四边形内的示例代码.Private Type tPoint dX As Single dY As Single End TypePrivate Sub Form_Load() Dim A(4) As tPoint '第一点坐标 A(1).dX = 207.3474 A(1).dY = 105.0965 '第二点坐标 A(2).dX = 267.3178 A(2).dY = 70.4726 '第三点坐标 A(3).dX = 460.7738 A(3).dY = 160.6826 '第四点坐标 A(4).dX = 340.3911 A(4).dY = 181.9093
Dim Points As tPoint'四边形内某点 Points.dX = 319.0326 Points.dY = 126.3982 ' Points.dY = 71.7361 '此点在四边形外围
MsgBox IsRect(A, Points) End Sub '将四边形的坐标按X坐标的大小进行排序 Private Function SortX(Rect() As tPoint) Dim i, j As Long Dim bak As tPoint For i = 1 To 3 For j = i + 1 To 4 If Rect(i).dX > Rect(j).dX Then bak.dX = Rect(i).dX bak.dY = Rect(i).dY
Rect(i).dX = Rect(j).dX Rect(i).dY = Rect(j).dY
Rect(j).dX = bak.dX Rect(j).dY = bak.dY
End If Next Next End FunctionPrivate Function IsRect(Rect() As tPoint, Point As tPoint) As Boolean IsRect = True
SortX Rect
Dim K(4) As Single Dim BK(2) As Single
'计算K1角度 If (Rect(2).dX - Rect(1).dX) <> 0 Then K(1) = Atn((Rect(2).dY - Rect(1).dY) / (Rect(2).dX - Rect(1).dX)) / 3.1415926 * 180 Else If (Rect(2).dY - Rect(1).dY) > 0 Then K(1) = 90 Else K(1) = -90 End If End If'计算K2角度 If (Rect(3).dX - Rect(1).dX) <> 0 Then K(2) = Atn((Rect(3).dY - Rect(1).dY) / (Rect(3).dX - Rect(1).dX)) / 3.1415926 * 180 Else If (Rect(3).dY - Rect(1).dY) > 0 Then K(2) = 90 Else K(2) = -90 End If End If
'计算K3角度 If (Rect(2).dX - Rect(4).dX) <> 0 Then K(3) = Atn((Rect(2).dY - Rect(4).dY) / (Rect(2).dX - Rect(4).dX)) / 3.1415926 * 180 + 180 Else If (Rect(2).dY - Rect(1).dY) > 0 Then K(3) = 90 Else K(3) = -90 End If End If'计算K4角度 If (Rect(3).dX - Rect(4).dX) <> 0 Then K(4) = Atn((Rect(3).dY - Rect(4).dY) / (Rect(3).dX - Rect(4).dX)) / 3.1415926 * 180 + 180 Else If (Rect(3).dY - Rect(4).dY) > 0 Then K(4) = 90 Else K(4) = 270 End If End If
'计算给定点相对于最左边点的角度 If (Point.dX - Rect(1).dX) <> 0 Then BK(1) = Atn((Point.dY - Rect(1).dY) / (Point.dX - Rect(1).dX)) / 3.1415926 * 180 Else If (Point.dY - Rect(1).dY) > 0 Then BK(1) = 90 Else BK(1) = -90 End If End If
'计算给定点相对最右边点角度 If (Point.dX - Rect(4).dX) <> 0 Then BK(2) = Atn((Point.dY - Rect(4).dY) / (Point.dX - Rect(4).dX)) / 3.1415926 * 180 + 180 Else If (Point.dY - Rect(4).dY) > 0 Then BK(2) = 90 Else BK(2) = 270 End If End If '根据角度进行判断. If K(1) > K(2) Then If BK(1) > K(1) Then IsRect = False If BK(1) < K(2) Then IsRect = False Else If BK(1) < K(1) Then IsRect = False If BK(1) > K(2) Then IsRect = False End If If K(3) > K(4) Then If BK(2) > K(3) Then IsRect = False If BK(2) < K(4) Then IsRect = False Else If BK(2) < K(3) Then IsRect = False If BK(2) > K(4) Then IsRect = False End IfEnd Function
Private Type tPoint dX As Single dY As Single End TypePrivate Sub Form_Load()'以下给定的15个点坐标 Dim A(15) As tPoint A(1).dX = 193.2916 A(2).dX = 198.2615 A(3).dX = 206.2685 A(4).dX = 209.3057 A(5).dX = 216.2083 A(6).dX = 218.1411 A(7).dX = 222.5587 A(8).dX = 224.7676 A(9).dX = 228.0809 A(10).dX = 231.9463 A(11).dX = 237.4684 A(12).dX = 239.4012 A(13).dX = 244.9233 A(14).dX = 248.2366 A(15).dX = 252.102 A(1).dY = 146.4412 A(2).dY = 154.994 A(3).dY = 155.5458 A(4).dY = 162.1673 A(5).dY = 162.4432 A(6).dY = 166.8576 A(7).dY = 166.3058 A(8).dY = 169.6165 A(9).dY = 170.4442 A(10).dY = 174.0309 A(11).dY = 175.1344 A(12).dY = 179.8247 A(13).dY = 180.6524 A(14).dY = 184.5149 A(15).dY = 183.6872 Dim cPoint As tPoint Dim Angle As SingleAngle = aveAngle(A, cPoint) MsgBox "拟合线段为一条经过点:X=" & cPoint.dX & ",Y=" & cPoint.dY & ".角度为:" & Angle & "的一条直线" End Sub '将坐标点按X坐标进行排序 Private Function SortX(Rect() As tPoint) Dim i, j As Long Dim bak As tPoint For i = 1 To UBound(Rect) - 1 For j = i + 1 To UBound(Rect) If Rect(i).dX > Rect(j).dX Then bak.dX = Rect(i).dX bak.dY = Rect(i).dY
Rect(i).dX = Rect(j).dX Rect(i).dY = Rect(j).dY
Rect(j).dX = bak.dX Rect(j).dY = bak.dY
End If Next Next End FunctionPrivate Function aveAngle(Rect() As tPoint, Point As tPoint) As Single SortX Rect
Dim mCount As Long Dim cAngle As Single
mCount = 0 cAngle = 0
'求出所有点之间的角度总和 For i = 1 To UBound(Rect) - 1 For j = i + 1 To UBound(Rect) If (Rect(j).dX - Rect(i).dX) <> 0 Then cAngle = cAngle + Atn((Rect(j).dY - Rect(i).dY) / (Rect(j).dX - Rect(i).dX)) / 3.1415926 * 180 Else If (Rect(j).dY - Rect(1).dY) > 0 Then cAngle = cAngle + 90 Else cAngle = cAngle - 90 End If End If mCount = mCount + 1 Next Next
'求平均角度 aveAngle = cAngle / mCount
For j = 1 To UBound(Rect) Point.dX = Point.dX + Rect(j).dX Point.dY = Point.dY + Rect(j).dY Next
'求出所有点之间的角度总和 For i = 1 To UBound(Rect) - 1 For j = i + 1 To UBound(Rect) If (Rect(j).dX - Rect(i).dX) <> 0 Then cAngle = cAngle + Atn((Rect(j).dY - Rect(i).dY) / (Rect(j).dX - Rect(i).dX)) / 3.1415926 * 180 Else If (Rect(j).dY - Rect(i).dY) > 0 Then ' 此处有更改 cAngle = cAngle + 90 Else cAngle = cAngle - 90 End If End If mCount = mCount + 1 Next Next
楼主的第一个问题很好解决啊 Private Declare Function PtInRect Lib "user32" Alias "PtInRect" (lpRect As RECT, pt As POINTAPI) As Long 或 Private Declare Function PtInRegion Lib "gdi32" Alias "PtInRegion" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long哪用这么复杂的计算呢
水平方向 x-x1 和 x-x2 的符号不同表示 x 在 (x1,y1) 内;垂直方向同理可得。
即:
bPtInRect = (Sgn((x-x1)*(x-x2)) = -1) and _
(sgn((y-y1)*(y-y2)) = -1)2)根据斜率决定下个点用 x 求 y 还是用 y 求 x。
一定有最左边的一个点与最右边的一个点.我们只要先分别计算 K1 K2 K3 K4 四个角度.再计算所在点相对于最左边及最右边点的角度.,看角度是否分别在 K1与K2之间,是否在 K3与K4之间.,那样就知此点是否在四边形之内了.
'判断某点是否有四边形内的示例代码.Private Type tPoint
dX As Single
dY As Single
End TypePrivate Sub Form_Load()
Dim A(4) As tPoint
'第一点坐标
A(1).dX = 207.3474
A(1).dY = 105.0965
'第二点坐标
A(2).dX = 267.3178
A(2).dY = 70.4726
'第三点坐标
A(3).dX = 460.7738
A(3).dY = 160.6826
'第四点坐标
A(4).dX = 340.3911
A(4).dY = 181.9093
Dim Points As tPoint'四边形内某点
Points.dX = 319.0326
Points.dY = 126.3982
' Points.dY = 71.7361 '此点在四边形外围
MsgBox IsRect(A, Points)
End Sub
'将四边形的坐标按X坐标的大小进行排序
Private Function SortX(Rect() As tPoint)
Dim i, j As Long
Dim bak As tPoint
For i = 1 To 3
For j = i + 1 To 4
If Rect(i).dX > Rect(j).dX Then
bak.dX = Rect(i).dX
bak.dY = Rect(i).dY
Rect(i).dX = Rect(j).dX
Rect(i).dY = Rect(j).dY
Rect(j).dX = bak.dX
Rect(j).dY = bak.dY
End If
Next
Next
End FunctionPrivate Function IsRect(Rect() As tPoint, Point As tPoint) As Boolean
IsRect = True
SortX Rect
Dim K(4) As Single
Dim BK(2) As Single
'计算K1角度
If (Rect(2).dX - Rect(1).dX) <> 0 Then
K(1) = Atn((Rect(2).dY - Rect(1).dY) / (Rect(2).dX - Rect(1).dX)) / 3.1415926 * 180
Else
If (Rect(2).dY - Rect(1).dY) > 0 Then
K(1) = 90
Else
K(1) = -90
End If
End If'计算K2角度
If (Rect(3).dX - Rect(1).dX) <> 0 Then
K(2) = Atn((Rect(3).dY - Rect(1).dY) / (Rect(3).dX - Rect(1).dX)) / 3.1415926 * 180
Else
If (Rect(3).dY - Rect(1).dY) > 0 Then
K(2) = 90
Else
K(2) = -90
End If
End If
'计算K3角度
If (Rect(2).dX - Rect(4).dX) <> 0 Then
K(3) = Atn((Rect(2).dY - Rect(4).dY) / (Rect(2).dX - Rect(4).dX)) / 3.1415926 * 180 + 180
Else
If (Rect(2).dY - Rect(1).dY) > 0 Then
K(3) = 90
Else
K(3) = -90
End If
End If'计算K4角度
If (Rect(3).dX - Rect(4).dX) <> 0 Then
K(4) = Atn((Rect(3).dY - Rect(4).dY) / (Rect(3).dX - Rect(4).dX)) / 3.1415926 * 180 + 180
Else
If (Rect(3).dY - Rect(4).dY) > 0 Then
K(4) = 90
Else
K(4) = 270
End If
End If
'计算给定点相对于最左边点的角度
If (Point.dX - Rect(1).dX) <> 0 Then
BK(1) = Atn((Point.dY - Rect(1).dY) / (Point.dX - Rect(1).dX)) / 3.1415926 * 180
Else
If (Point.dY - Rect(1).dY) > 0 Then
BK(1) = 90
Else
BK(1) = -90
End If
End If
'计算给定点相对最右边点角度
If (Point.dX - Rect(4).dX) <> 0 Then
BK(2) = Atn((Point.dY - Rect(4).dY) / (Point.dX - Rect(4).dX)) / 3.1415926 * 180 + 180
Else
If (Point.dY - Rect(4).dY) > 0 Then
BK(2) = 90
Else
BK(2) = 270
End If
End If
'根据角度进行判断.
If K(1) > K(2) Then
If BK(1) > K(1) Then IsRect = False
If BK(1) < K(2) Then IsRect = False
Else
If BK(1) < K(1) Then IsRect = False
If BK(1) > K(2) Then IsRect = False
End If If K(3) > K(4) Then
If BK(2) > K(3) Then IsRect = False
If BK(2) < K(4) Then IsRect = False
Else
If BK(2) < K(3) Then IsRect = False
If BK(2) > K(4) Then IsRect = False
End IfEnd Function
CreateEllipticRgn
PtInRegion
(当然这系列的API可以创建更多的图形)
水平方向 x-x1 和 x-x2 的符号不同表示 x 在 (x1,
y1x2) 内;Private Type tPoint
dX As Single
dY As Single
End TypePrivate Sub Form_Load()'以下给定的15个点坐标
Dim A(15) As tPoint
A(1).dX = 193.2916
A(2).dX = 198.2615
A(3).dX = 206.2685
A(4).dX = 209.3057
A(5).dX = 216.2083
A(6).dX = 218.1411
A(7).dX = 222.5587
A(8).dX = 224.7676
A(9).dX = 228.0809
A(10).dX = 231.9463
A(11).dX = 237.4684
A(12).dX = 239.4012
A(13).dX = 244.9233
A(14).dX = 248.2366
A(15).dX = 252.102
A(1).dY = 146.4412
A(2).dY = 154.994
A(3).dY = 155.5458
A(4).dY = 162.1673
A(5).dY = 162.4432
A(6).dY = 166.8576
A(7).dY = 166.3058
A(8).dY = 169.6165
A(9).dY = 170.4442
A(10).dY = 174.0309
A(11).dY = 175.1344
A(12).dY = 179.8247
A(13).dY = 180.6524
A(14).dY = 184.5149
A(15).dY = 183.6872
Dim cPoint As tPoint
Dim Angle As SingleAngle = aveAngle(A, cPoint) MsgBox "拟合线段为一条经过点:X=" & cPoint.dX & ",Y=" & cPoint.dY & ".角度为:" & Angle & "的一条直线"
End Sub
'将坐标点按X坐标进行排序
Private Function SortX(Rect() As tPoint)
Dim i, j As Long
Dim bak As tPoint
For i = 1 To UBound(Rect) - 1
For j = i + 1 To UBound(Rect)
If Rect(i).dX > Rect(j).dX Then
bak.dX = Rect(i).dX
bak.dY = Rect(i).dY
Rect(i).dX = Rect(j).dX
Rect(i).dY = Rect(j).dY
Rect(j).dX = bak.dX
Rect(j).dY = bak.dY
End If
Next
Next
End FunctionPrivate Function aveAngle(Rect() As tPoint, Point As tPoint) As Single
SortX Rect
Dim mCount As Long
Dim cAngle As Single
mCount = 0
cAngle = 0
'求出所有点之间的角度总和
For i = 1 To UBound(Rect) - 1
For j = i + 1 To UBound(Rect)
If (Rect(j).dX - Rect(i).dX) <> 0 Then
cAngle = cAngle + Atn((Rect(j).dY - Rect(i).dY) / (Rect(j).dX - Rect(i).dX)) / 3.1415926 * 180
Else
If (Rect(j).dY - Rect(1).dY) > 0 Then
cAngle = cAngle + 90
Else
cAngle = cAngle - 90
End If
End If
mCount = mCount + 1
Next
Next
'求平均角度
aveAngle = cAngle / mCount
For j = 1 To UBound(Rect)
Point.dX = Point.dX + Rect(j).dX
Point.dY = Point.dY + Rect(j).dY
Next
'求拟合点坐标
Point.dX = Point.dX / UBound(Rect)
Point.dY = Point.dY / UBound(Rect)
End Function
'求出所有点之间的角度总和
For i = 1 To UBound(Rect) - 1
For j = i + 1 To UBound(Rect)
If (Rect(j).dX - Rect(i).dX) <> 0 Then
cAngle = cAngle + Atn((Rect(j).dY - Rect(i).dY) / (Rect(j).dX - Rect(i).dX)) / 3.1415926 * 180
Else
If (Rect(j).dY - Rect(i).dY) > 0 Then
' 此处有更改 cAngle = cAngle + 90
Else
cAngle = cAngle - 90
End If
End If
mCount = mCount + 1
Next
Next
Private Declare Function PtInRect Lib "user32" Alias "PtInRect" (lpRect As RECT, pt As POINTAPI) As Long
或
Private Declare Function PtInRegion Lib "gdi32" Alias "PtInRegion" (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long哪用这么复杂的计算呢
1、我已知一点的坐标值以及矩形的四个顶点坐标,要求这个点是否在方框内。这个问题如果对比内存影响区的范围是否可以简单点?