使用matplotlib

时间:2018-02-15 13:54:10

标签: python matplotlib geometry ellipse

是否有人知道是否可以使用matplotlib.patches.Ellipse计算两个椭圆的重叠区域。

我必须像这样省略:

enter image description here

我想计算重叠区域和各个椭圆的比例。 仅使用Ellipse

中的matplotlib.patches是否可行

1 个答案:

答案 0 :(得分:1)

您无法使用[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } public class Hook { public static long SWEH_CHILDID_SELF = 0; //SetWinEventHook() flags public enum SWEH_dwFlags : uint { WINEVENT_OUTOFCONTEXT = 0x0000, // Events are ASYNC WINEVENT_SKIPOWNTHREAD = 0x0001, // Don't call back for events on installer's thread WINEVENT_SKIPOWNPROCESS = 0x0002, // Don't call back for events on installer's process WINEVENT_INCONTEXT = 0x0004 // Events are SYNC, this causes your dll to be injected into every process } //SetWinEventHook() events public enum SWEH_Events : uint { EVENT_MIN = 0x00000001, EVENT_MAX = 0x7FFFFFFF, EVENT_SYSTEM_SOUND = 0x0001, EVENT_SYSTEM_ALERT = 0x0002, EVENT_SYSTEM_FOREGROUND = 0x0003, EVENT_SYSTEM_MENUSTART = 0x0004, EVENT_SYSTEM_MENUEND = 0x0005, EVENT_SYSTEM_MENUPOPUPSTART = 0x0006, EVENT_SYSTEM_MENUPOPUPEND = 0x0007, EVENT_SYSTEM_CAPTURESTART = 0x0008, EVENT_SYSTEM_CAPTUREEND = 0x0009, EVENT_SYSTEM_MOVESIZESTART = 0x000A, EVENT_SYSTEM_MOVESIZEEND = 0x000B, EVENT_SYSTEM_CONTEXTHELPSTART = 0x000C, EVENT_SYSTEM_CONTEXTHELPEND = 0x000D, EVENT_SYSTEM_DRAGDROPSTART = 0x000E, EVENT_SYSTEM_DRAGDROPEND = 0x000F, EVENT_SYSTEM_DIALOGSTART = 0x0010, EVENT_SYSTEM_DIALOGEND = 0x0011, EVENT_SYSTEM_SCROLLINGSTART = 0x0012, EVENT_SYSTEM_SCROLLINGEND = 0x0013, EVENT_SYSTEM_SWITCHSTART = 0x0014, EVENT_SYSTEM_SWITCHEND = 0x0015, EVENT_SYSTEM_MINIMIZESTART = 0x0016, EVENT_SYSTEM_MINIMIZEEND = 0x0017, EVENT_SYSTEM_DESKTOPSWITCH = 0x0020, EVENT_SYSTEM_END = 0x00FF, EVENT_OEM_DEFINED_START = 0x0101, EVENT_OEM_DEFINED_END = 0x01FF, EVENT_UIA_EVENTID_START = 0x4E00, EVENT_UIA_EVENTID_END = 0x4EFF, EVENT_UIA_PROPID_START = 0x7500, EVENT_UIA_PROPID_END = 0x75FF, EVENT_CONSOLE_CARET = 0x4001, EVENT_CONSOLE_UPDATE_REGION = 0x4002, EVENT_CONSOLE_UPDATE_SIMPLE = 0x4003, EVENT_CONSOLE_UPDATE_SCROLL = 0x4004, EVENT_CONSOLE_LAYOUT = 0x4005, EVENT_CONSOLE_START_APPLICATION = 0x4006, EVENT_CONSOLE_END_APPLICATION = 0x4007, EVENT_CONSOLE_END = 0x40FF, EVENT_OBJECT_CREATE = 0x8000, // hwnd ID idChild is created item EVENT_OBJECT_DESTROY = 0x8001, // hwnd ID idChild is destroyed item EVENT_OBJECT_SHOW = 0x8002, // hwnd ID idChild is shown item EVENT_OBJECT_HIDE = 0x8003, // hwnd ID idChild is hidden item EVENT_OBJECT_REORDER = 0x8004, // hwnd ID idChild is parent of zordering children EVENT_OBJECT_FOCUS = 0x8005, // hwnd ID idChild is focused item EVENT_OBJECT_SELECTION = 0x8006, // hwnd ID idChild is selected item (if only one), or idChild is OBJID_WINDOW if complex EVENT_OBJECT_SELECTIONADD = 0x8007, // hwnd ID idChild is item added EVENT_OBJECT_SELECTIONREMOVE = 0x8008, // hwnd ID idChild is item removed EVENT_OBJECT_SELECTIONWITHIN = 0x8009, // hwnd ID idChild is parent of changed selected items EVENT_OBJECT_STATECHANGE = 0x800A, // hwnd ID idChild is item w/ state change EVENT_OBJECT_LOCATIONCHANGE = 0x800B, // hwnd ID idChild is moved/sized item EVENT_OBJECT_NAMECHANGE = 0x800C, // hwnd ID idChild is item w/ name change EVENT_OBJECT_DESCRIPTIONCHANGE = 0x800D, // hwnd ID idChild is item w/ desc change EVENT_OBJECT_VALUECHANGE = 0x800E, // hwnd ID idChild is item w/ value change EVENT_OBJECT_PARENTCHANGE = 0x800F, // hwnd ID idChild is item w/ new parent EVENT_OBJECT_HELPCHANGE = 0x8010, // hwnd ID idChild is item w/ help change EVENT_OBJECT_DEFACTIONCHANGE = 0x8011, // hwnd ID idChild is item w/ def action change EVENT_OBJECT_ACCELERATORCHANGE = 0x8012, // hwnd ID idChild is item w/ keybd accel change EVENT_OBJECT_INVOKED = 0x8013, // hwnd ID idChild is item invoked EVENT_OBJECT_TEXTSELECTIONCHANGED = 0x8014, // hwnd ID idChild is item w? test selection change EVENT_OBJECT_CONTENTSCROLLED = 0x8015, EVENT_SYSTEM_ARRANGMENTPREVIEW = 0x8016, EVENT_OBJECT_END = 0x80FF, EVENT_AIA_START = 0xA000, EVENT_AIA_END = 0xAFFF } //SetWinEventHook() Object Ids public enum SWEH_ObjectId : long { OBJID_WINDOW = 0x00000000, OBJID_SYSMENU = 0xFFFFFFFF, OBJID_TITLEBAR = 0xFFFFFFFE, OBJID_MENU = 0xFFFFFFFD, OBJID_CLIENT = 0xFFFFFFFC, OBJID_VSCROLL = 0xFFFFFFFB, OBJID_HSCROLL = 0xFFFFFFFA, OBJID_SIZEGRIP = 0xFFFFFFF9, OBJID_CARET = 0xFFFFFFF8, OBJID_CURSOR = 0xFFFFFFF7, OBJID_ALERT = 0xFFFFFFF6, OBJID_SOUND = 0xFFFFFFF5, OBJID_QUERYCLASSNAMEIDX = 0xFFFFFFF4, OBJID_NATIVEOM = 0xFFFFFFF0 } private static SWEH_dwFlags WinEventHookInternalFlags = SWEH_dwFlags.WINEVENT_OUTOFCONTEXT | SWEH_dwFlags.WINEVENT_SKIPOWNPROCESS | SWEH_dwFlags.WINEVENT_SKIPOWNTHREAD; public delegate void WinEventDelegate(IntPtr hWinEventHook, SWEH_Events eventType, IntPtr hwnd, SWEH_ObjectId idObject, long idChild, uint dwEventThread, uint dwmsEventTime); public static IntPtr WinEventHookRange(SWEH_Events _eventFrom, SWEH_Events _eventTo, WinEventDelegate _delegate, uint idProcess, uint idThread) { new UIPermission(UIPermissionWindow.AllWindows).Demand(); return UnsafeNativeMethods.SetWinEventHook(_eventFrom, _eventTo, IntPtr.Zero, _delegate, idProcess, idThread, WinEventHookInternalFlags); } public static IntPtr WinEventHookOne(SWEH_Events _event, WinEventDelegate _delegate, uint idProcess, uint idThread) { new UIPermission(UIPermissionWindow.AllWindows).Demand(); return UnsafeNativeMethods.SetWinEventHook(_event, _event, IntPtr.Zero, _delegate, idProcess, idThread, WinEventHookInternalFlags); } public static bool WinEventUnhook(IntPtr hWinEventHook) { return UnsafeNativeMethods.UnhookWinEvent(hWinEventHook); } public static uint GetWindowThread(IntPtr hWnd) { new UIPermission(UIPermissionWindow.AllWindows).Demand(); return UnsafeNativeMethods.GetWindowThreadProcessId(hWnd, IntPtr.Zero); } public static RECT GetWindowRect(IntPtr hWnd) { RECT rect = new RECT(); bool _result = SafeNativeMethods.GetWindowRect(hWnd, ref rect); return rect; } } [SuppressUnmanagedCodeSecurity] internal static class SafeNativeMethods { [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); } [SuppressUnmanagedCodeSecurity] internal static class UnsafeNativeMethods { [DllImport("user32.dll", SetLastError = true)] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr voidProcessId); [DllImport("user32.dll", SetLastError = false)] public static extern IntPtr SetWinEventHook(Hook.SWEH_Events eventMin, Hook.SWEH_Events eventMax, IntPtr hmodWinEventProc, Hook.WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, Hook.SWEH_dwFlags dwFlags); [DllImport("user32.dll", SetLastError = false)] public static extern bool UnhookWinEvent(IntPtr hWinEventHook); } 计算相交的区域(至少不是我所知),但您可以使用matplotlib执行此操作,然后使用shapely可视化结果。这是一个快速演示:

matplotlib

结果情节如下所示:

result of above code

计算区域(打印到终端)是:

from matplotlib import pyplot as plt
from shapely.geometry.point import Point
from shapely import affinity
from matplotlib.patches import Polygon
import numpy as np

def create_ellipse(center, lengths, angle=0):
    """
    create a shapely ellipse. adapted from
    https://gis.stackexchange.com/a/243462
    """
    circ = Point(center).buffer(1)
    ell = affinity.scale(circ, int(lengths[0]), int(lengths[1]))
    ellr = affinity.rotate(ell, angle)
    return ellr

fig,ax = plt.subplots()

##these next few lines are pretty important because
##otherwise your ellipses might only be displayed partly
##or may be distorted
ax.set_xlim([-5,5])
ax.set_ylim([-5,5])
ax.set_aspect('equal')

##first ellipse in blue
ellipse1 = create_ellipse((0,0),(2,4),10)
verts1 = np.array(ellipse1.exterior.coords.xy)
patch1 = Polygon(verts1.T, color = 'blue', alpha = 0.5)
ax.add_patch(patch1)

##second ellipse in red    
ellipse2 = create_ellipse((1,-1),(3,2),50)
verts2 = np.array(ellipse2.exterior.coords.xy)
patch2 = Polygon(verts2.T,color = 'red', alpha = 0.5)
ax.add_patch(patch2)

##the intersect will be outlined in black
intersect = ellipse1.intersection(ellipse2)
verts3 = np.array(intersect.exterior.coords.xy)
patch3 = Polygon(verts3.T, facecolor = 'none', edgecolor = 'black')
ax.add_patch(patch3)

##compute areas and ratios 
print('area of ellipse 1:',ellipse1.area)
print('area of ellipse 2:',ellipse2.area)
print('area of intersect:',intersect.area)
print('intersect/ellipse1:', intersect.area/ellipse1.area)
print('intersect/ellipse2:', intersect.area/ellipse2.area)


plt.show()

请注意,我调整了代码以从this post生成椭圆形多边形。希望这会有所帮助。