我想通过拖动一个矩形来选择一个椭圆,问题是:如何判断某个椭圆与一个矩形相交?

解决方案 »

  1.   

    下面简化为:如何判断一个点(X,Y)在给定左上角坐标(X1,Y1)与右下角坐标(X2,Y2)的椭圆内部??
      

  2.   

    1。根据(x1,y1),(x2,y2)求椭圆的长轴(x2-x1)/2 短轴(y1-y2)/2
    2。求焦距:sqr(长轴平方+短轴平方)
    3。求中心x=(x1+x2)/2,y=(y1+y2)/2
    4。根据1,2,3求椭圆标准方程
    5。代入已知点(a,b),判断是否大于1,如果是,则在外部;不是,就在内部了
      

  3.   

    使用api:
    1.用CreateRectRgn建立矩形区域、用CreateEllipticRgn建立椭圆区域。
    2.用CreateRectRgn建立结果区域。
    3.用CombineRgn对矩形、椭圆区域进行and操作,并判断返回值,如果是0表示操作失败,如果是1则无交集,如果是其他值则有交集
      

  4.   

    to  lsftest() :
    有没有示例代码?谢谢!
      

  5.   

    模块:
    Option Explicit
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '矩形
    Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type'点
    Public Type POINTAPI
        x As Long
        y As Long
    End Type
    Public Type LOGBRUSH
            lbStyle As Long
            lbColor As Long
            lbHatch As Long
    End Type
    Public Declare Function DrawEdge Lib "user32" (ByVal hDC As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Boolean
    Public Declare Function MoveToEx Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, lpPoint As Long) As Long
    Public Declare Function LineTo Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long
    Public Declare Function Rectangle Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Public Declare Function Polyline Lib "gdi32" (ByVal hDC As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
    Public Declare Function Polygon Lib "gdi32" (ByVal hDC As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
    Public Declare Function Ellipse Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Public Declare Function CreateBrushIndirect Lib "gdi32" (lpLogBrush As LOGBRUSH) As Long
    Public Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
    Public Declare Function StretchBlt Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    '样式
    Public Const BS_HATCHED = 2
    Public Const BS_NULL = 1
    Public Const BS_SOLID = 0'底纹
    Public Const HS_BDIAGONAL = 3               '  /////
    Public Const HS_CROSS = 4                   '  +++++
    Public Const HS_DIAGCROSS = 5               '  xxxxx
    Public Const HS_FDIAGONAL = 2               '  \\\\\
    Public Const HS_HORIZONTAL = 0              '  -----
    Public Const HS_VERTICAL = 1                '  |||||Public Const PS_NULL = 5
    Public Const PS_SOLID = 0
    Public Const PS_DOT = 2
    Public Const PS_DASH = 1
    Public Const PS_DASHDOT = 3
    Public Const PS_DASHDOTDOT = 4
    Public Const PS_INSIDEFRAME = 6
    Public Const SRCAND = &H8800C6
    Public Const SRCCOPY = &HCC0020
    Public Const SRCERASE = &H440328
    Public Const SRCINVERT = &H660046
    Public Const SRCPAINT = &HEE0086
    '用于程序客户区域绘图信息结构体
    Public Type PAINTSTRUCT
       hDC As Long
       fErase As Long
       rcPaint As RECT
       fRestore As Long
       fIncUpdate As Long
       rgbReserved(0 To 31) As Byte
    End Type'定义位图的类型、宽度、高度、颜色格式和位数据块
    Public Type BITMAP
        bmType As Long
        bmWidth As Long
        bmHeight As Long
        bmWidthBytes As Long
        bmPlanes As Integer
        bmBitsPixel As Integer
        bmBits As Long
    End Type
    '指定窗体进行绘图准备,通过PAINTSTRUCT结构体来初始化。
    Public Declare Function BeginPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    '在绘图完成后,标记窗体绘图结束。
    Public Declare Function EndPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long
    '用于获取给定绘图对象的信息。
    '取决于绘图对象的不同,可以在给定缓冲区中填入BITMAP, DIBSECTION, EXTLOGPEN, LOGBRUSH, LOGFONT 或者 LOGPEN 结构
    Public Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
    '将一个对象选入指定的设备场景(画布)中,该对象自动替换掉同一类型的前一对象。
    Public Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
    '删除一个逻辑画笔、画刷、字体、位图、区域或者调色板
    Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    '获取给定窗口或者整个屏幕的画布,用于在上面绘图。
    Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    '释放标准Windows设备场景资源。
    Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long
    '创建兼容的内存设备场景
    Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
    '创建设备相关位图
    Public Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    '创建指定纯色的逻辑画刷
    Public Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
    '使用指定画刷填充矩形区域
    Public Declare Function FillRect Lib "user32" (ByVal hDC As Long, lpRect As RECT, ByVal hBrush As Long) As Long
    '从源画布到目标画布的比特块传送其彩色数据
    Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
    '返回桌面窗体(屏幕)的句柄
    Public Declare Function GetDesktopWindow Lib "user32" () As Long
    '获取系统度量单位和系统设置,所有尺寸均以点 Pixel 表示
    Public Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
    '水平滚动条上的矢量位图宽度
    Public Const SM_CYHSCROLL = 3
    '水平滚动条上的矢量位图高度
    Public Const SM_CXVSCROLL = 2
    Public Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Public Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long
    Public Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Public Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
    Public Const RGN_AND = 1
    Public Const RGN_OR = 2
    Public Const RGN_XOR = 3
    Public Const RGN_COPY = 5
    Public Const RGN_DIFF = 4
    窗体:
    3个按钮、1个Label、1个PictureBox代码:
    Option Explicit
    Dim glngBrush As Long, glngPen As Long
    Private Sub Command1_Click()
        Rectangle Picture1.hDC, 15, 15, 90, 16
        Picture1.Refresh
    End SubPrivate Sub Command2_Click()
        Rectangle Picture1.hDC, 50, 50, 80, 14
        Picture1.Refresh
    End SubPrivate Sub Command3_Click()
        Dim MyRgn As Long, OutRgn As Long, InRgn As Long, R As Long
        MyRgn = CreateRectRgn(0, 0, 0, 0)
        OutRgn = CreateRectRgn(15, 15, 90, 16)
        InRgn = CreateRectRgn(50, 50, 80, 14)
        R = CombineRgn(MyRgn, OutRgn, InRgn, RGN_AND)
        If R = 1 Or R = 0 Then
            Label1 = "No"
        Else
            Label1 = "Yes"
        End If
    End SubPrivate Sub Form_Load()
        Call SetDrawStyleFromValue(Picture1.hDC, vbRed, 0, 1, vbBlue, -1)
    End SubPublic Sub SetDrawStyleFromValue(lngHDc As Long, PenColor As Long, PenStyle As Byte, PenWidth As Byte, FillColor As Long, FillStyle As Integer)
    '功能:根据指定值设置当前的画笔的画刷
        Dim vBrush As LOGBRUSH
        Dim lngPen As Long, lngBrush As Long
        
        If glngBrush <> 0 Then DeleteObject glngBrush
        If glngPen <> 0 Then DeleteObject glngPen
        
        '画笔
        lngPen = CreatePen(PenStyle, IIf(PenWidth < 1, 1, PenWidth), PenColor)
        glngPen = SelectObject(lngHDc, lngPen)
        
        '画刷
        vBrush.lbColor = FillColor
        If FillStyle = -1 Then
            vBrush.lbStyle = BS_NULL
        ElseIf FillStyle = -2 Then
            vBrush.lbStyle = BS_SOLID
        Else
            vBrush.lbStyle = BS_HATCHED
            vBrush.lbHatch = FillStyle
        End If
        lngBrush = CreateBrushIndirect(vBrush)
        glngBrush = SelectObject(lngHDc, lngBrush)
    End Sub
      

  6.   

    窗体代码改为:
    Option Explicit
    Dim glngBrush As Long, glngPen As Long
    Private Sub Command1_Click()
        Rectangle Picture1.hDC, 15, 15, 90, 90
        Picture1.Refresh
    End SubPrivate Sub Command2_Click()
        Ellipse Picture1.hDC, 50, 50, 190, 190
        Picture1.Refresh
    End SubPrivate Sub Command3_Click()
        Dim MyRgn As Long, OutRgn As Long, InRgn As Long, R As Long
        MyRgn = CreateRectRgn(0, 0, 0, 0)
        OutRgn = CreateRectRgn(15, 15, 90, 90)
        InRgn = CreateEllipticRgn(50, 50, 190, 190)
        R = CombineRgn(MyRgn, OutRgn, InRgn, RGN_AND)
        If R = 1 Or R = 0 Then
            Label1 = "No"
        Else
            Label1 = "Yes"
        End If
    End SubPrivate Sub Form_Load()
        Call SetDrawStyleFromValue(Picture1.hDC, vbRed, 0, 1, vbBlue, -1)
    End SubPublic Sub SetDrawStyleFromValue(lngHDc As Long, PenColor As Long, PenStyle As Byte, PenWidth As Byte, FillColor As Long, FillStyle As Integer)
    '功能:根据指定值设置当前的画笔的画刷
        Dim vBrush As LOGBRUSH
        Dim lngPen As Long, lngBrush As Long
        
        If glngBrush <> 0 Then DeleteObject glngBrush
        If glngPen <> 0 Then DeleteObject glngPen
        
        '画笔
        lngPen = CreatePen(PenStyle, IIf(PenWidth < 1, 1, PenWidth), PenColor)
        glngPen = SelectObject(lngHDc, lngPen)
        
        '画刷
        vBrush.lbColor = FillColor
        If FillStyle = -1 Then
            vBrush.lbStyle = BS_NULL
        ElseIf FillStyle = -2 Then
            vBrush.lbStyle = BS_SOLID
        Else
            vBrush.lbStyle = BS_HATCHED
            vBrush.lbHatch = FillStyle
        End If
        lngBrush = CreateBrushIndirect(vBrush)
        glngBrush = SelectObject(lngHDc, lngBrush)
    End Sub