【问题标题】:Region.IsVisible(PointF) has very slow performance for large floating point valuesRegion.IsVisible(PointF) 对于大浮点值的性能非常慢
【发布时间】:2017-08-25 15:11:50
【问题描述】:

我遇到了一个奇怪的性能问题,如果能解释一下我遇到的行为,那就太好了。

我正在使用 System.Drawing.Region.IsVisible(PointF) 来确定一个点是否在多边形内。这通常工作得很好,但昨天我注意到如果多边形很复杂并且它由大的 x 和 y 值组成,IsVisible 方法的性能会变得非常慢。

下面是一些重现问题的代码(以及显示多边形形状的图像),对于大数组大小感到抱歉,但在问题出现之前,多边形需要非常复杂。

在原始点上调用 IsVisible 时,我的机器需要 460 651 毫秒才能完成,而当我首先将所有点除以 1000,然后调用该方法时,需要 1 毫秒。为什么我看到时间上有这么大的差异?我不认为浮点数的实际值会影响性能。

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;

namespace PerformanceTest
{
    class Program
    {
        static void Main(string[] args)
        {

            // Create complex polygon with large x and y values
            float[] xValues = {1.014498E+07f, 1.016254E+07f, 1.019764E+07f, 1.021519E+07f, 1.023274E+07f, 1.026785E+07f, 1.026785E+07f, 1.02854E+07f, 1.02854E+07f, 1.030295E+07f, 1.03205E+07f, 1.033805E+07f, 1.035561E+07f, 1.037316E+07f, 1.039071E+07f, 1.040826E+07f, 1.042581E+07f, 1.044337E+07f, 1.046092E+07f, 1.047847E+07f, 1.049602E+07f, 1.051357E+07f, 1.054868E+07f, 1.056623E+07f, 1.058378E+07f, 1.060133E+07f, 1.061888E+07f, 1.061888E+07f, 1.063644E+07f, 1.065399E+07f, 1.068909E+07f, 1.068909E+07f, 1.070664E+07f, 1.07242E+07f, 1.074175E+07f, 1.074175E+07f, 1.07593E+07f, 1.07593E+07f, 1.077685E+07f, 1.07944E+07f, 1.07944E+07f, 1.081196E+07f, 1.081196E+07f, 1.081196E+07f, 1.082951E+07f, 1.084706E+07f, 1.084706E+07f, 1.086461E+07f, 1.086461E+07f, 1.088216E+07f, 1.089971E+07f, 1.091727E+07f, 1.093482E+07f, 1.098747E+07f, 1.100503E+07f, 1.102258E+07f, 1.104013E+07f, 1.105768E+07f, 1.107523E+07f, 1.107523E+07f, 1.109279E+07f, 1.109279E+07f, 1.109279E+07f, 1.109279E+07f, 1.109279E+07f, 1.111034E+07f, 1.111034E+07f, 1.111034E+07f, 1.111034E+07f, 1.111034E+07f, 1.112789E+07f, 1.112789E+07f, 1.112789E+07f, 1.114544E+07f, 1.116299E+07f, 1.118054E+07f, 1.11981E+07f, 1.12332E+07f, 1.125075E+07f, 1.12683E+07f, 1.128586E+07f, 1.130341E+07f, 1.135606E+07f, 1.137361E+07f, 1.139117E+07f, 1.140872E+07f, 1.144382E+07f, 1.146137E+07f, 1.147893E+07f, 1.149648E+07f, 1.151403E+07f, 1.153158E+07f, 1.154913E+07f, 1.156669E+07f, 1.156669E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.158424E+07f, 1.156669E+07f, 1.156669E+07f, 1.151403E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.149648E+07f, 1.153158E+07f, 1.154913E+07f, 1.156669E+07f, 1.156669E+07f, 1.158424E+07f, 1.160179E+07f, 1.160179E+07f, 1.161934E+07f, 1.165444E+07f, 1.1672E+07f, 1.168955E+07f, 1.17071E+07f, 1.172465E+07f, 1.17422E+07f, 1.175976E+07f, 1.177731E+07f, 1.179486E+07f, 1.181241E+07f, 1.182996E+07f, 1.184752E+07f, 1.186507E+07f, 1.188262E+07f, 1.190017E+07f, 1.190017E+07f, 1.191772E+07f, 1.191772E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.193528E+07f, 1.195283E+07f, 1.197038E+07f, 1.198793E+07f, 1.200548E+07f, 1.202303E+07f, 1.204059E+07f, 1.205814E+07f, 1.207569E+07f, 1.209324E+07f, 1.211079E+07f, 1.212835E+07f, 1.21459E+07f, 1.216345E+07f, 1.2181E+07f, 1.219855E+07f, 1.221611E+07f, 1.221611E+07f, 1.223366E+07f, 1.225121E+07f, 1.226876E+07f, 1.226876E+07f, 1.228631E+07f, 1.230386E+07f, 1.230386E+07f, 1.230386E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.232142E+07f, 1.235652E+07f, 1.235652E+07f, 1.237407E+07f, 1.237407E+07f, 1.239162E+07f, 1.239162E+07f, 1.240918E+07f, 1.242673E+07f, 1.242673E+07f, 1.244428E+07f, 1.247938E+07f, 1.249694E+07f, 1.251449E+07f, 1.253204E+07f, 1.254959E+07f, 1.256714E+07f, 1.258469E+07f, 1.260225E+07f, 1.263735E+07f, 1.26549E+07f, 1.267245E+07f, 1.269001E+07f, 1.270756E+07f, 1.272511E+07f, 1.272511E+07f, 1.274266E+07f, 1.274266E+07f, 1.276021E+07f, 1.276021E+07f, 1.277776E+07f, 1.277776E+07f, 1.277776E+07f, 1.277776E+07f, 1.279532E+07f, 1.279532E+07f, 1.279532E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.281287E+07f, 1.279532E+07f, 1.277776E+07f, 1.276021E+07f, 1.276021E+07f, 1.274266E+07f, 1.274266E+07f, 1.272511E+07f, 1.272511E+07f, 1.272511E+07f, 1.274266E+07f, 1.276021E+07f, 1.279532E+07f, 1.281287E+07f, 1.283042E+07f, 1.284797E+07f, 1.286552E+07f, 1.288308E+07f, 1.290063E+07f, 1.291818E+07f, 1.293573E+07f, 1.295328E+07f, 1.295328E+07f, 1.297084E+07f, 1.297084E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.298839E+07f, 1.300594E+07f, 1.300594E+07f, 1.302349E+07f, 1.304104E+07f, 1.305859E+07f, 1.30937E+07f, 1.311125E+07f, 1.31288E+07f, 1.314635E+07f, 1.316391E+07f, 1.318146E+07f, 1.319901E+07f, 1.321656E+07f, 1.323411E+07f, 1.325167E+07f, 1.325167E+07f, 1.326922E+07f, 1.326922E+07f, 1.328677E+07f, 1.330432E+07f, 1.330432E+07f, 1.330432E+07f, 1.332187E+07f, 1.333943E+07f, 1.335698E+07f, 1.335698E+07f, 1.337453E+07f, 1.339208E+07f, 1.340963E+07f, 1.340963E+07f, 1.342718E+07f, 1.344474E+07f, 1.346229E+07f, 1.347984E+07f, 1.349739E+07f, 1.351494E+07f, 1.355005E+07f, 1.35676E+07f, 1.36027E+07f, 1.363781E+07f, 1.367291E+07f, 1.367291E+07f, 1.370801E+07f, 1.372557E+07f, 1.376067E+07f, 1.377822E+07f, 1.381333E+07f, 1.383088E+07f, 1.384843E+07f, 1.386598E+07f, 1.390109E+07f, 1.391864E+07f, 1.391864E+07f, 1.393619E+07f, 1.395374E+07f, 1.397129E+07f, 1.398884E+07f, 1.40064E+07f, 1.402395E+07f, 1.405905E+07f, 1.409416E+07f, 1.412926E+07f, 1.414681E+07f, 1.418191E+07f, 1.419947E+07f, 1.421702E+07f, 1.423457E+07f, 1.426967E+07f, 1.430478E+07f, 1.433988E+07f, 1.435743E+07f, 1.437499E+07f, 1.439254E+07f, 1.439254E+07f, 1.442764E+07f, 1.442764E+07f, 1.444519E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.446274E+07f, 1.444519E+07f, 1.442764E+07f, 1.441009E+07f, 1.439254E+07f, 1.437499E+07f, 1.435743E+07f, 1.433988E+07f, 1.432233E+07f, 1.430478E+07f, 1.430478E+07f, 1.426967E+07f, 1.426967E+07f, 1.423457E+07f, 1.421702E+07f, 1.418191E+07f, 1.414681E+07f, 1.412926E+07f, 1.409416E+07f, 1.405905E+07f, 1.402395E+07f, 1.40064E+07f, 1.395374E+07f, 1.393619E+07f, 1.391864E+07f, 1.390109E+07f, 1.390109E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.388353E+07f, 1.390109E+07f, 1.391864E+07f, 1.393619E+07f, 1.395374E+07f, 1.398884E+07f, 1.398884E+07f, 1.40064E+07f, 1.402395E+07f, 1.402395E+07f, 1.40415E+07f, 1.405905E+07f, 1.40766E+07f, 1.412926E+07f, 1.414681E+07f, 1.416436E+07f, 1.418191E+07f, 1.419947E+07f, 1.421702E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.423457E+07f, 1.421702E+07f, 1.419947E+07f, 1.418191E+07f, 1.416436E+07f, 1.416436E+07f, 1.412926E+07f, 1.411171E+07f, 1.409416E+07f, 1.40766E+07f, 1.405905E+07f, 1.40415E+07f, 1.402395E+07f, 1.40064E+07f, 1.397129E+07f, 1.397129E+07f, 1.395374E+07f, 1.393619E+07f, 1.393619E+07f, 1.391864E+07f, 1.391864E+07f, 1.390109E+07f, 1.388353E+07f, 1.388353E+07f, 1.386598E+07f, 1.384843E+07f, 1.383088E+07f, 1.379577E+07f, 1.376067E+07f, 1.372557E+07f, 1.370801E+07f, 1.369046E+07f, 1.365536E+07f, 1.363781E+07f, 1.362026E+07f, 1.36027E+07f, 1.358515E+07f, 1.35676E+07f, 1.35325E+07f, 1.351494E+07f, 1.349739E+07f, 1.347984E+07f, 1.346229E+07f, 1.344474E+07f, 1.339208E+07f, 1.337453E+07f, 1.335698E+07f, 1.333943E+07f, 1.332187E+07f, 1.332187E+07f, 1.330432E+07f, 1.326922E+07f, 1.325167E+07f, 1.323411E+07f, 1.321656E+07f, 1.319901E+07f, 1.316391E+07f, 1.314635E+07f, 1.31288E+07f, 1.311125E+07f, 1.307615E+07f, 1.304104E+07f, 1.302349E+07f, 1.300594E+07f, 1.300594E+07f, 1.300594E+07f, 1.300594E+07f, 1.300594E+07f, 1.300594E+07f, 1.300594E+07f, 1.302349E+07f, 1.304104E+07f, 1.307615E+07f, 1.30937E+07f, 1.311125E+07f, 1.314635E+07f, 1.316391E+07f, 1.318146E+07f, 1.319901E+07f, 1.321656E+07f, 1.323411E+07f, 1.323411E+07f, 1.323411E+07f, 1.323411E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.325167E+07f, 1.323411E+07f, 1.323411E+07f, 1.321656E+07f, 1.319901E+07f, 1.318146E+07f, 1.316391E+07f, 1.314635E+07f, 1.31288E+07f, 1.305859E+07f, 1.304104E+07f, 1.298839E+07f, 1.295328E+07f, 1.291818E+07f, 1.288308E+07f, 1.286552E+07f, 1.284797E+07f, 1.283042E+07f, 1.279532E+07f, 1.277776E+07f, 1.276021E+07f, 1.272511E+07f, 1.270756E+07f, 1.269001E+07f, 1.26549E+07f, 1.263735E+07f, 1.260225E+07f, 1.258469E+07f, 1.256714E+07f, 1.256714E+07f, 1.254959E+07f, 1.253204E+07f, 1.253204E+07f, 1.253204E+07f, 1.251449E+07f, 1.251449E+07f, 1.251449E+07f, 1.251449E+07f, 1.251449E+07f, 1.249694E+07f, 1.249694E+07f, 1.249694E+07f, 1.249694E+07f, 1.247938E+07f, 1.247938E+07f, 1.246183E+07f, 1.244428E+07f, 1.240918E+07f, 1.239162E+07f, 1.235652E+07f, 1.233897E+07f, 1.230386E+07f, 1.226876E+07f, 1.225121E+07f, 1.221611E+07f, 1.219855E+07f, 1.219855E+07f, 1.2181E+07f, 1.216345E+07f, 1.216345E+07f, 1.21459E+07f, 1.21459E+07f, 1.212835E+07f, 1.212835E+07f, 1.212835E+07f, 1.212835E+07f, 1.212835E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.211079E+07f, 1.209324E+07f, 1.207569E+07f, 1.207569E+07f, 1.204059E+07f, 1.202303E+07f, 1.200548E+07f, 1.198793E+07f, 1.197038E+07f, 1.195283E+07f, 1.193528E+07f, 1.191772E+07f, 1.190017E+07f, 1.188262E+07f, 1.186507E+07f, 1.181241E+07f, 1.181241E+07f, 1.179486E+07f, 1.177731E+07f, 1.177731E+07f, 1.177731E+07f, 1.175976E+07f, 1.175976E+07f, 1.17422E+07f, 1.17422E+07f, 1.17422E+07f, 1.17422E+07f, 1.17422E+07f, 1.17422E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.172465E+07f, 1.17071E+07f, 1.168955E+07f, 1.1672E+07f, 1.163689E+07f, 1.161934E+07f, 1.160179E+07f, 1.156669E+07f, 1.154913E+07f, 1.151403E+07f, 1.149648E+07f, 1.147893E+07f, 1.146137E+07f, 1.144382E+07f, 1.144382E+07f, 1.139117E+07f, 1.139117E+07f, 1.137361E+07f, 1.137361E+07f, 1.137361E+07f, 1.137361E+07f, 1.137361E+07f, 1.137361E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.135606E+07f, 1.133851E+07f, 1.133851E+07f, 1.133851E+07f, 1.133851E+07f, 1.133851E+07f, 1.130341E+07f, 1.130341E+07f, 1.128586E+07f, 1.12683E+07f, 1.125075E+07f, 1.121565E+07f, 1.116299E+07f, 1.112789E+07f, 1.107523E+07f, 1.105768E+07f, 1.102258E+07f, 1.098747E+07f, 1.095237E+07f, 1.091727E+07f, 1.089971E+07f, 1.088216E+07f, 1.086461E+07f, 1.082951E+07f, 1.081196E+07f, 1.081196E+07f, 1.07944E+07f, 1.07944E+07f, 1.077685E+07f, 1.07593E+07f, 1.07593E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.074175E+07f, 1.07593E+07f, 1.07593E+07f, 1.077685E+07f, 1.07944E+07f, 1.07944E+07f, 1.081196E+07f, 1.082951E+07f, 1.082951E+07f, 1.086461E+07f, 1.088216E+07f, 1.089971E+07f, 1.089971E+07f, 1.091727E+07f, 1.091727E+07f, 1.091727E+07f, 1.091727E+07f, 1.091727E+07f, 1.091727E+07f, 1.089971E+07f, 1.088216E+07f, 1.082951E+07f, 1.07944E+07f, 1.07593E+07f, 1.070664E+07f, 1.068909E+07f, 1.067154E+07f, 1.065399E+07f, 1.063644E+07f, 1.061888E+07f, 1.060133E+07f, 1.058378E+07f, 1.056623E+07f, 1.054868E+07f, 1.051357E+07f, 1.049602E+07f, 1.047847E+07f, 1.046092E+07f, 1.042581E+07f, 1.039071E+07f, 1.030295E+07f, 1.026785E+07f, 1.023274E+07f, 1.019764E+07f, 1.018009E+07f, 1.016254E+07f, 1.014498E+07f, 1.010988E+07f, 1.009233E+07f, 1.007478E+07f, 1.005722E+07f, 1.003967E+07f, 1.002212E+07f, 9969464f, 9916809f, 9881705f, 9864154f, 9846602f, 9829050f, 9811497f, 9793945f, 9776394f, 9741290f, 9723738f, 9688635f, 9653531f, 9653531f, 9618427f, 9618427f, 9600875f, 9600875f, 9600875f, 9583323f, 9565771f, 9565771f, 9530667f, 9530667f, 9530667f, 9530667f, 9530667f, 9530667f, 9530667f, 9530667f, 9548219f, 9565771f, 9583323f, 9618427f, 9653531f, 9671083f, 9688635f, 9706186f, 9741290f, 9758842f, 9811497f, 9829050f, 9864154f, 9881705f, 9916809f, 9934361f, 9951913f, 9987016f, 1.000457E+07f, 1.003967E+07f, 1.005722E+07f, 1.007478E+07f, 1.010988E+07f, 1.014498E+07f, 1.016254E+07f, 1.016254E+07f, 1.018009E+07f, 1.019764E+07f, 1.021519E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.023274E+07f, 1.021519E+07f, 1.019764E+07f, 1.016254E+07f, 1.014498E+07f, 1.012743E+07f, 1.009233E+07f, 1.003967E+07f, 1.000457E+07f, 9951913f, 9934361f, 9899257f, 9881705f, 9864154f, 9846602f, 9829050f, 9793945f, 9758842f, 9723738f, 9688635f, 9653531f, 9635979f, 9618427f, 9583323f, 9565771f, 9530667f, 9513116f, 9495564f, 9478012f, 9460460f, 9460460f, 9442908f, 9425357f, 9425357f, 9407805f, 9390253f, 9390253f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9372701f, 9390253f, 9407805f, 9425357f, 9460460f, 9495564f, 9513116f, 9583323f, 9600875f, 9635979f, 9653531f, 9688635f, 9706186f, 9723738f, 9758842f, 9793945f, 9811497f, 9846602f};
            float[] yValues = { 7286825f, 7286825f, 7269351f, 7269351f, 7269351f, 7269351f, 7251876f, 7251876f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7234401f, 7216927f, 7199453f, 7181979f, 7181979f, 7164504f, 7164504f, 7147029f, 7129555f, 7112081f, 7077132f, 7042183f, 7024709f, 7007235f, 6972285f, 6954811f, 6937337f, 6919863f, 6902388f, 6884913f, 6867439f, 6867439f, 6832491f, 6815016f, 6797541f, 6780067f, 6762593f, 6762593f, 6745119f, 6745119f, 6727644f, 6727644f, 6710169f, 6710169f, 6710169f, 6710169f, 6710169f, 6710169f, 6710169f, 6727644f, 6762593f, 6780067f, 6832491f, 6849965f, 6867439f, 6902388f, 6937337f, 6954811f, 6972285f, 6989760f, 7024709f, 7042183f, 7077132f, 7094607f, 7112081f, 7129555f, 7129555f, 7129555f, 7129555f, 7129555f, 7129555f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7147029f, 7129555f, 7112081f, 7077132f, 7059657f, 7007235f, 6972285f, 6954811f, 6937337f, 6902388f, 6867439f, 6832491f, 6815016f, 6797541f, 6780067f, 6710169f, 6710169f, 6692695f, 6675221f, 6640272f, 6622797f, 6605323f, 6587849f, 6570375f, 6535425f, 6517951f, 6500477f, 6483003f, 6465528f, 6448053f, 6448053f, 6430579f, 6430579f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6413105f, 6430579f, 6448053f, 6483003f, 6500477f, 6552900f, 6570375f, 6622797f, 6640272f, 6657747f, 6675221f, 6692695f, 6710169f, 6745119f, 6762593f, 6780067f, 6797541f, 6849965f, 6867439f, 6902388f, 6954811f, 6972285f, 6989760f, 7007235f, 7042183f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7059657f, 7042183f, 7042183f, 7024709f, 7007235f, 6989760f, 6989760f, 6972285f, 6954811f, 6937337f, 6919863f, 6902388f, 6867439f, 6832491f, 6815016f, 6797541f, 6780067f, 6762593f, 6745119f, 6727644f, 6710169f, 6692695f, 6675221f, 6657747f, 6657747f, 6640272f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6622797f, 6640272f, 6657747f, 6692695f, 6692695f, 6710169f, 6727644f, 6745119f, 6762593f, 6780067f, 6780067f, 6797541f, 6815016f, 6832491f, 6849965f, 6867439f, 6884913f, 6902388f, 6919863f, 6937337f, 6954811f, 6972285f, 6989760f, 7007235f, 7024709f, 7042183f, 7059657f, 7077132f, 7094607f, 7112081f, 7129555f, 7147029f, 7164504f, 7181979f, 7199453f, 7234401f, 7234401f, 7251876f, 7251876f, 7269351f, 7286825f, 7304299f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7321773f, 7304299f, 7286825f, 7269351f, 7251876f, 7234401f, 7216927f, 7199453f, 7181979f, 7164504f, 7147029f, 7129555f, 7112081f, 7094607f, 7077132f, 7042183f, 7024709f, 7007235f, 6989760f, 6954811f, 6937337f, 6919863f, 6902388f, 6849965f, 6832491f, 6815016f, 6797541f, 6780067f, 6780067f, 6762593f, 6762593f, 6762593f, 6745119f, 6745119f, 6745119f, 6745119f, 6745119f, 6745119f, 6762593f, 6762593f, 6797541f, 6832491f, 6867439f, 6884913f, 6884913f, 6919863f, 6954811f, 6954811f, 6972285f, 6989760f, 7007235f, 7042183f, 7042183f, 7059657f, 7077132f, 7094607f, 7094607f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7112081f, 7094607f, 7077132f, 7042183f, 7024709f, 7024709f, 7007235f, 6989760f, 6989760f, 6972285f, 6954811f, 6937337f, 6937337f, 6919863f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6902388f, 6919863f, 6919863f, 6954811f, 6972285f, 6972285f, 6989760f, 7024709f, 7042183f, 7059657f, 7094607f, 7112081f, 7129555f, 7164504f, 7181979f, 7199453f, 7234401f, 7251876f, 7269351f, 7286825f, 7321773f, 7321773f, 7339248f, 7339248f, 7356723f, 7374197f, 7374197f, 7374197f, 7374197f, 7374197f, 7391671f, 7391671f, 7409145f, 7409145f, 7426620f, 7426620f, 7426620f, 7444095f, 7444095f, 7461569f, 7479043f, 7496517f, 7513992f, 7513992f, 7513992f, 7531467f, 7548941f, 7548941f, 7566415f, 7601364f, 7618839f, 7636313f, 7653787f, 7671261f, 7688736f, 7706211f, 7741159f, 7793583f, 7828531f, 7846005f, 7880955f, 7880955f, 7898429f, 7898429f, 7915903f, 7933377f, 7933377f, 7950852f, 7950852f, 7950852f, 7950852f, 7950852f, 7950852f, 7950852f, 7968327f, 7985801f, 8003275f, 8020749f, 8038224f, 8055699f, 8073173f, 8090647f, 8108121f, 8125596f, 8160545f, 8178019f, 8195493f, 8212968f, 8212968f, 8230443f, 8247917f, 8265391f, 8282865f, 8282865f, 8282865f, 8282865f, 8282865f, 8282865f, 8282865f, 8282865f, 8265391f, 8230443f, 8212968f, 8195493f, 8178019f, 8160545f, 8160545f, 8143071f, 8143071f, 8125596f, 8108121f, 8108121f, 8090647f, 8090647f, 8073173f, 8038224f, 8038224f, 8020749f, 8020749f, 8003275f, 7985801f, 7985801f, 7968327f, 7950852f, 7950852f, 7933377f, 7933377f, 7933377f, 7933377f, 7915903f, 7898429f, 7898429f, 7898429f, 7898429f, 7898429f, 7898429f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7880955f, 7898429f, 7898429f, 7933377f, 7968327f, 7985801f, 8003275f, 8020749f, 8055699f, 8073173f, 8108121f, 8108121f, 8143071f, 8178019f, 8178019f, 8212968f, 8212968f, 8230443f, 8247917f, 8265391f, 8282865f, 8282865f, 8317815f, 8335289f, 8352763f, 8387712f, 8405186f, 8422661f, 8440134f, 8457609f, 8475084f, 8510033f, 8527506f, 8544981f, 8562456f, 8614878f, 8632353f, 8667302f, 8684777f, 8737200f, 8772149f, 8789622f, 8824572f, 8842046f, 8859521f, 8876994f, 8894469f, 8929418f, 8929418f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8946893f, 8911944f, 8894469f, 8859521f, 8824572f, 8789622f, 8772149f, 8702250f, 8684777f, 8667302f, 8632353f, 8614878f, 8597405f, 8562456f, 8544981f, 8510033f, 8492558f, 8475084f, 8457609f, 8440134f, 8422661f, 8405186f, 8387712f, 8370237f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8352763f, 8370237f, 8370237f, 8387712f, 8387712f, 8405186f, 8422661f, 8422661f, 8440134f, 8457609f, 8492558f, 8527506f, 8544981f, 8562456f, 8579930f, 8597405f, 8614878f, 8632353f, 8649828f, 8667302f, 8702250f, 8719725f, 8737200f, 8772149f, 8789622f, 8807097f, 8824572f, 8842046f, 8876994f, 8894469f, 8911944f, 8929418f, 8946893f, 8964366f, 8964366f, 8981841f, 8999316f, 9016790f, 9034265f, 9034265f, 9051738f, 9051738f, 9051738f, 9051738f, 9051738f, 9051738f, 9051738f, 9016790f, 8999316f, 8964366f, 8946893f, 8929418f, 8911944f, 8876994f, 8859521f, 8842046f, 8824572f, 8807097f, 8789622f, 8772149f, 8754674f, 8702250f, 8667302f, 8649828f, 8632353f, 8614878f, 8597405f, 8579930f, 8562456f, 8544981f, 8510033f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8492558f, 8510033f, 8544981f, 8544981f, 8562456f, 8562456f, 8597405f, 8614878f, 8632353f, 8667302f, 8702250f, 8719725f, 8754674f, 8789622f, 8824572f, 8842046f, 8859521f, 8876994f, 8911944f, 8929418f, 8964366f, 8964366f, 8999316f, 9016790f, 9034265f, 9086688f, 9104162f, 9139110f, 9156585f, 9174060f, 9209009f, 9243957f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9261432f, 9243957f, 9226482f, 9191534f, 9174060f, 9156585f, 9086688f, 9051738f, 9034265f, 8999316f, 8981841f, 8964366f, 8929418f, 8894469f, 8876994f, 8842046f, 8824572f, 8807097f, 8789622f, 8772149f, 8754674f, 8702250f, 8684777f, 8667302f, 8667302f, 8649828f, 8614878f, 8597405f, 8579930f, 8562456f, 8562456f, 8527506f, 8510033f, 8492558f, 8475084f, 8440134f, 8422661f, 8422661f, 8387712f, 8370237f, 8370237f, 8370237f, 8370237f, 8370237f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8335289f, 8352763f, 8370237f, 8405186f, 8440134f, 8457609f, 8492558f, 8510033f, 8527506f, 8562456f, 8579930f, 8597405f, 8597405f, 8632353f, 8632353f, 8667302f, 8702250f, 8719725f, 8754674f, 8754674f, 8754674f, 8754674f, 8754674f, 8754674f, 8754674f, 8754674f, 8737200f, 8719725f, 8702250f, 8684777f, 8667302f, 8649828f, 8632353f, 8614878f, 8562456f, 8527506f, 8440134f, 8422661f, 8387712f, 8352763f, 8317815f, 8300340f, 8282865f, 8265391f, 8247917f, 8212968f, 8212968f, 8160545f, 8143071f, 8125596f, 8108121f, 8108121f, 8090647f, 8090647f, 8073173f, 8073173f, 8055699f, 8055699f, 8055699f, 8038224f, 8038224f, 8038224f, 8038224f, 8038224f, 8020749f, 8020749f, 8003275f, 8003275f, 7985801f, 7950852f, 7933377f, 7915903f, 7915903f, 7880955f, 7863480f, 7846005f, 7828531f, 7793583f, 7776108f, 7758633f, 7741159f, 7723685f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7706211f, 7723685f, 7723685f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7741159f, 7723685f, 7723685f, 7688736f, 7671261f, 7653787f, 7583889f, 7566415f, 7513992f, 7461569f, 7444095f, 7409145f, 7374197f, 7356723f, 7321773f, 7304299f, 7286825f, 7269351f, 7251876f, 7234401f, 7199453f, 7181979f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7164504f, 7181979f, 7199453f };

            PointF[] points = xValues.Zip(yValues, (x, y) => new PointF(x, y)).ToArray();


            // Create a region with the original values 
            GraphicsPath pathWithOriginalPoints = new GraphicsPath();
            pathWithOriginalPoints.AddPolygon(points);
            Region regionFromOriginalPoints = new Region(pathWithOriginalPoints);

            // Create a region with the values divided by 1000
            GraphicsPath pathDividedBy1000 = new GraphicsPath();
            pathDividedBy1000.AddPolygon(points.Select(p => new PointF(p.X/1000f, p.Y/1000f)).ToArray());
            Region regionDividedby1000 = new Region(pathDividedBy1000);


            // Time call to Region.IsVisible(PointF)
            var stopwatch = Stopwatch.StartNew();
            Console.WriteLine("Computing region.IsVisible for points divided by 1000:");
            regionDividedby1000.IsVisible(new PointF(0f, 0f));
            var dividedBy1000Timing = stopwatch.ElapsedMilliseconds;
            Console.WriteLine($"Elapsed time: {dividedBy1000Timing} ms");

            stopwatch.Restart();
            Console.WriteLine("Computing region.IsVisible for original points");
            regionFromOriginalPoints.IsVisible(new PointF(0f, 0f));
            var originalTiming = stopwatch.ElapsedMilliseconds;
            Console.WriteLine($"Elapsed time: {originalTiming} ms");
        }
    }
}

【问题讨论】:

  • 是否也尝试过将 IsVisible(point, graphics) 与缩放的图形对象一起使用?其中一些数字得到了一个有点大的 fopr gdi 位图。你真的需要完全精确吗?
  • 不,我没有尝试使用缩放的图形对象。在我的代码中发生这种情况的地方,我实际上并没有绘制任何东西,在它被绘制之前它被转换为屏幕坐标。您假设我不需要使用这么大的数字进行计算是正确的,我通过缩小多边形和点来解决它。但是,我仍然对可能导致性能缓慢的原因感到好奇,只是因为多边形中的数字很大:)
  • 嗯,Region 上的文档相当稀少。但这确实是有道理的:如果您的形状(即 Regions 是什么)很大,那么必须检查更多的点才能进行 IsVisible 测试。我不知道,但我想它会创建某种具有 1 位深度的位图来表示它。我确实记得创建区域是一项非常昂贵的操作..
  • 我同意如果形状非常大,则必须检查更多点以执行 IsVisible thest 是有道理的。但我仍然不明白为什么形状的实际 x 和 y 值有多大很重要。如果形状的值除以 1000,则具有相同数量点的相同复杂形状几乎不需要时间来计算。
  • 抱歉给您带来了困惑,我猜我的句子有点模棱两可。我的意思是我将形状的分开,但点数仍然相同。例如,点不是 (10000, 5000),而是 (10, 5)。这就是我觉得奇怪的地方,将每个点的值相除会使计算速度更快。

标签: c# winforms gdi+ region graphicspath


【解决方案1】:

TLTR

进行一次Region.IsVisible(Point) 调用所需的时间根本不取决于点数。相反,它取决于完全准确地覆盖该区域所需的矩形数量。这取决于..:

  • 这些点描述的形状以及通常的形状
  • 形状的大小。

示例 1:一个矩形区域有四个点,并且总是需要 一个矩形 来覆盖它。如果您要添加大量点,只要它们都位于矩形的边上,这不会改变!

示例 2:圆形区域也 (!) 有四个点 () 但您需要完全覆盖它的矩形数量**取决于那个圈子。请看底部的图形!


全文

Region 不是我所说的“有据可查”的课程。

您可以看到内部工作似乎依赖于RegionData,可以通过调用var RData = your Region.GetRegionData()来访问。

这里也是一样的:至少可以这么说,没有很好的记录。也许我只是找不到它,但似乎没有关于这些字节的结构的信息..

(下面的数字表明,每个点需要 1 个字节作为类型指示符,加上两个浮点坐标的 2+4 个字节。这就像 GraphicsPath 中的 PathPoints&PathTypes。在你的例子中有 924+1 个点和 1+2*4 个字节,这构成了 8325 个字节;另外还有 27 个字节;8 个可以保持缩放..)

但有一点很有趣:从您的Regionsboth 中查看RegionData 可以很容易地看到它们具有相同 大小..:@ 987654335@。这表明RegionData 无论如何都与额外时间没有直接关系..

但是还有另一个,有点同样神秘,阅读:不完整的电话:GetRegionScans。 MSDN 是这么说的:

返回一个近似此区域的 RectangleF 结构数组 在应用指定的矩阵变换之后。

首先让我们看看如果我们为您的两个区域提取这些“扫描”会发生什么:

Matrix M = new Matrix();

var scans1 = regionFromOriginalPoints.GetRegionScans(M);
var scans2 = regionDividedby1000.GetRegionScans(M);

我使用简单的单位矩阵 (*),即没有转换,结果如下:

scans1.Length = 5.960.690
scans2.Length = 5.956

因此它会创建 1000 倍以上 的矩形来近似 Region,而且,你瞧,这样做也需要很多时间..:

这并不奇怪:未缩放的路径覆盖了一个巨大的区域,并且为了近似它,我预计需要更多的矩形。我不知道近似值是如何工作的,但它可能会决定,即使返回 RectangleF,也不需要任何边小于 1 像素的矩形。

所以我得出结论,IsVisible 调用在内部需要创建那些近似矩形,并且它需要足够的它们来覆盖区域内的每个完整像素。 (请注意,Region 不支持部分/抗锯齿像素!)区域边界越大,适合的像素越多,扫描过程所需的时间就越长。

我还假设严格来说是扫描过程占用了时间。

下一步:发送RectangleF.Contains(Point) 应该非常快,即使是一百万次调用。让我们来看看;当我测量这个时:

int hits = 0;
PointF pt = new PointF(123.456f, 789.012f);
foreach (RectangleF r in scans1) if (r.Contains(pt)) hits++;

..只需42ms 即可完成。因此,一旦您缓存扫描矩形,您就可以轻松地对它们进行大量命中测试而不是单独进行IsVisible 调用..

以下是数字摘要:

你原来的路径:

多边形点数 = 924
regionData1.Length = 8.352
scans1.Length = 5.960.690
经过的时间1:453.187 毫秒

缩小1000的路径:

多边形点数 = 924
regionData2.Length = 8.352
scans2.Length= 5.956
经过时间2:2毫秒

全套扫描所用时间:41 毫秒


最后:为了更好地理解扫描矩形,我用交替颜色近似了一个圆形:

for (int i = 0; i < scans.Length; i++)
     g.FillRectangle(i%2 == 0 ? Brushes.ForestGreen : Brushes.Salmon, scans[i]);

您可以看到,在顶部和底部,每一行都是一个矩形,因为这里的曲线是平坦的,x 坐标快速向外移动。我们越靠近中间,矩形就越大(即更高)……所以我们可以看到近似值严格遵循 rows..

即使边界矩形的高度大于宽度也是如此,并且使用列,可以使用更少的矩形:

这里两个椭圆(222x111111x222)都近似为85水平条纹。由于曲率不同,那比圆要小..


(*) - 我们跳过了Matrix;但它可用于通过放大或缩小数据来修改结果。 圆有一个Height222像素,它需要135扫描矩形来近似它。如果我们放大Matrix,(即Graphics对象用来表示Region): m.Scale(10,10); 它需要 1315 扫描矩形来覆盖放大的圆圈。

因此可以使用按0.001f 缩小的矩阵来代替缩放数据点;但它只会测试按比例缩小的版本,并且可能会错过边框周围的像素或包含错误的像素。所以最好只使用你真正需要的正确比例..

(* *) 请注意,循环 GraphicsPath 确实有 13 PathPoints;但这些实际上只是四个实际点(加上第一个重复以关闭图形)加上每对点之间的两个控制点;所以 5 + 4*2 = 13。另请注意,GraphicsPath 中的任何线是直线或贝塞尔曲线。这包括圆弧、椭圆和圆!

【讨论】:

  • 伟大的调查!对于更多的矩形,扫描过程需要更长的时间是有道理的。但是,我不确定我是否理解您为什么需要更多矩形来获得更大的形状的原因。不应该也可以缩放矩形吗?
  • 但您需要遵循曲线并包含每个完整像素!试着想象一下对一个圆进行扫描过程:如果它小到 3x3,那么您需要的矩形数量可以低至 1-3 个;不要让它变大,比如 30x30 并用矩形来近似:每隔一行或每隔一行至少需要一个,所以需要 15-30 个矩形。我试过了,对于一个圆圈 确实需要每行一个矩形.
  • 我明白了,有道理!谢谢你的解释!
  • 看我附加的插图!
【解决方案2】:

我们一直在努力解决同样的问题:对于一个 50k 点的多边形,在 IsVisible() 方法后面构建矩形需要 45 秒。我们试图缓存这些数据,但最终我们有超过 100 万个矩形;对于多个区域,我们需要缓存数百兆字节的数据。

最后我们转向了 PNPoly 算法,只需要几毫秒:

https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html

这里是c#版本:

    public bool IsVisible(Point p, List<Point> points)
    {
        int i, j = points.Count - 1;
        bool isVisible = false;
        for (i = 0; i < points.Count; i++)
        {
            if (points[i].Y < p.Y && points[j].Y >= p.Y 
                || points[j].Y < p.Y && points[i].Y >= p.Y)
            {
                if (points[i].X + (p.Y - points[i].Y) / (points[j].Y - points[i].Y) 
                    * (points[j].X - points[i].X) < p.X)
                {
                    isVisible = !isVisible;
                }
            }
            j = i;
        }
        return isVisible;
    }

【讨论】:

    猜你喜欢
    • 2023-02-02
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多