Changeset 5948


Ignore:
Timestamp:
Nov 12, 2008, 12:14:33 PM (16 years ago)
Author:
rwilson
Message:

More NumPy? changes.

Location:
anuga_core/source_numpy_conversion/anuga/utilities
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source_numpy_conversion/anuga/utilities/numerical_tools.py

    r5902 r5948  
    77from warnings import warn
    88
    9 ##from numpy import ndarray, array, sum, inner, ravel, sqrt, searchsorted, sort, concatenate, float, arange
    109import numpy
     10
     11from anuga.config import Float
    1112
    1213# Getting an infinite number to use when using Numeric
     
    7980        v2 = [1.0, 0.0] # Unit vector along the x-axis
    8081       
    81     v1 = ensure_numeric(v1, numpy.float)
    82     v2 = ensure_numeric(v2, numpy.float)   
     82    v1 = ensure_numeric(v1, Float)
     83    v2 = ensure_numeric(v2, Float)   
    8384   
    8485    # Normalise
     
    130131    """
    131132   
    132     return numpy.array([-v[1], v[0]], numpy.float)
     133    return numpy.array([-v[1], v[0]], Float)
    133134
    134135   
     
    252253
    253254    if typecode is None:
    254 ##NumPy        if isinstance(A, ArrayType):
    255255        if type(A) == numpy.ndarray:
    256256            return A
     
    258258            return numpy.array(A)
    259259    else:
    260 ##NumPy        if isinstance(A, ArrayType):
    261260        if type(A) == numpy.ndarray:
    262 ##NumPy            if A.typecode == typecode:
    263261            if A.dtype == typecode:
    264262                return numpy.array(A)  #FIXME: Shouldn't this just return A?
     
    267265        else:
    268266            import types                            ##
    269             from numpy import str                   ##
    270267            if isinstance(A, types.StringType):     ##
    271                 return numpy.array(A, dtype=int)          ##
     268                return numpy.array(A, dtype=int)    ##
    272269            return numpy.array(A, typecode)
    273270
  • anuga_core/source_numpy_conversion/anuga/utilities/polygon.py

    r5902 r5948  
    1010#    #print 'Could not find scipy - using Numeric'
    1111
    12 ##from numpy import float, int, zeros, ones, array, concatenate, reshape, dot, allclose, newaxis, ascontiguousarray
    1312import numpy
    14 
    1513
    1614from math import sqrt
    1715from anuga.utilities.numerical_tools import ensure_numeric
    1816from anuga.geospatial_data.geospatial_data import ensure_absolute
    19 
    20 
    21 def point_on_line(point, line, rtol=0.0, atol=0.0):
     17from anuga.config import Float, Int
     18
     19
     20def point_on_line(point, line, rtol=1.0e-5, atol=1.0e-8):
    2221    """Determine whether a point is on a line segment
    2322
     
    3231    """
    3332
    34     # FIXME(Ole): Perhaps make defaults as in allclose: rtol=1.0e-5, atol=1.0e-8
    35 
    3633    point = ensure_numeric(point)
    3734    line = ensure_numeric(line)
     
    4542
    4643
    47 
    48 
    49 
    50 def intersection(line0, line1):
     44######
     45# Result functions used in intersection() below for collinear lines.
     46# (p0,p1) defines line 0, (p2,p3) defines line 1.
     47######
     48
     49# result functions for possible states
     50def lines_dont_coincide(p0,p1,p2,p3):               return (3, None)
     51def lines_0_fully_included_in_1(p0,p1,p2,p3):       return (2, numpy.array([p0,p1]))
     52def lines_1_fully_included_in_0(p0,p1,p2,p3):       return (2, numpy.array([p2,p3]))
     53def lines_overlap_same_direction(p0,p1,p2,p3):      return (2, numpy.array([p0,p3]))
     54def lines_overlap_same_direction2(p0,p1,p2,p3):     return (2, numpy.array([p2,p1]))
     55def lines_overlap_opposite_direction(p0,p1,p2,p3):  return (2, numpy.array([p0,p2]))
     56def lines_overlap_opposite_direction2(p0,p1,p2,p3): return (2, numpy.array([p3,p1]))
     57
     58# this function called when an impossible state is found
     59def lines_error(p1, p2, p3, p4): raise RuntimeError, "INTERNAL ERROR"
     60
     61#                     0s1    0e1    1s0    1e0   # line 0 starts on 1, 0 ends 1, 1 starts 0, 1 ends 0
     62collinear_result = { (False, False, False, False): lines_dont_coincide,
     63                     (False, False, False, True ): lines_error,
     64                     (False, False, True,  False): lines_error,
     65                     (False, False, True,  True ): lines_1_fully_included_in_0,
     66                     (False, True,  False, False): lines_error,
     67                     (False, True,  False, True ): lines_overlap_opposite_direction2,
     68                     (False, True,  True,  False): lines_overlap_same_direction2,
     69                     (False, True,  True,  True ): lines_1_fully_included_in_0,
     70                     (True,  False, False, False): lines_error,
     71                     (True,  False, False, True ): lines_overlap_same_direction,
     72                     (True,  False, True,  False): lines_overlap_opposite_direction,
     73                     (True,  False, True,  True ): lines_1_fully_included_in_0,
     74                     (True,  True,  False, False): lines_0_fully_included_in_1,
     75                     (True,  True,  False, True ): lines_0_fully_included_in_1,
     76                     (True,  True,  True,  False): lines_0_fully_included_in_1,
     77                     (True,  True,  True,  True ): lines_0_fully_included_in_1
     78                   }
     79
     80def intersection(line0, line1, rtol=1.0e-5, atol=1.0e-8):
     81    """Returns intersecting point between two line segments or None
     82    (if parallel or no intersection is found).
     83
     84    However, if parallel lines coincide partly (i.e. shara a common segment,
     85    the line segment where lines coincide is returned
     86   
     87
     88    Inputs:
     89        line0, line1: Each defined by two end points as in: [[x0, y0], [x1, y1]]
     90                      A line can also be a 2x2 numpy array with each row
     91                      corresponding to a point.
     92
     93
     94    Output:
     95        status, value
     96
     97        where status and value is interpreted as follows
     98       
     99        status == 0: no intersection, value set to None.
     100        status == 1: intersection point found and returned in value as [x,y].
     101        status == 2: Collinear overlapping lines found. Value takes the form [[x0,y0], [x1,y1]].
     102        status == 3: Collinear non-overlapping lines. Value set to None.
     103        status == 4: Lines are parallel with a fixed distance apart. Value set to None.
     104   
     105    """
     106
     107    # FIXME (Ole): Write this in C
     108
     109    line0 = ensure_numeric(line0, Float)
     110    line1 = ensure_numeric(line1, Float)   
     111
     112    x0 = line0[0,0]; y0 = line0[0,1]
     113    x1 = line0[1,0]; y1 = line0[1,1]
     114
     115    x2 = line1[0,0]; y2 = line1[0,1]
     116    x3 = line1[1,0]; y3 = line1[1,1]
     117
     118    denom = (y3-y2)*(x1-x0) - (x3-x2)*(y1-y0)
     119    u0 = (x3-x2)*(y0-y2) - (y3-y2)*(x0-x2)
     120    u1 = (x2-x0)*(y1-y0) - (y2-y0)*(x1-x0)
     121       
     122    if numpy.allclose(denom, 0.0, rtol=rtol, atol=atol):
     123        # Lines are parallel - check if they are collinear
     124        if numpy.allclose([u0, u1], 0.0, rtol=rtol, atol=atol):
     125            # We now know that the lines are collinear
     126            state_tuple = (point_on_line([x0, y0], line1, rtol=rtol, atol=atol),
     127                           point_on_line([x1, y1], line1, rtol=rtol, atol=atol),
     128                           point_on_line([x2, y2], line0, rtol=rtol, atol=atol),
     129                           point_on_line([x3, y3], line0, rtol=rtol, atol=atol))
     130
     131            return collinear_result[state_tuple]([x0,y0],[x1,y1],[x2,y2],[x3,y3])
     132        else:
     133            # Lines are parallel but aren't collinear
     134            return 4, None #FIXME (Ole): Add distance here instead of None
     135    else:
     136        # Lines are not parallel, check if they intersect
     137        u0 = u0/denom
     138        u1 = u1/denom       
     139
     140        x = x0 + u0*(x1-x0)
     141        y = y0 + u0*(y1-y0)
     142
     143        # Sanity check - can be removed to speed up if needed
     144        assert numpy.allclose(x, x2 + u1*(x3-x2), rtol=rtol, atol=atol)
     145        assert numpy.allclose(y, y2 + u1*(y3-y2), rtol=rtol, atol=atol)       
     146
     147        # Check if point found lies within given line segments
     148        if 0.0 <= u0 <= 1.0 and 0.0 <= u1 <= 1.0:
     149            # We have intersection
     150            return 1, numpy.array([x, y])
     151        else:
     152            # No intersection
     153            return 0, None
     154
     155
     156def NEW_C_intersection(line0, line1):
     157    #FIXME(Ole): To write in C
    51158    """Returns intersecting point between two line segments or None
    52159    (if parallel or no intersection is found).
     
    75182    """
    76183
    77     # FIXME (Ole): Write this in C
    78 
    79     line0 = ensure_numeric(line0, numpy.float)
    80     line1 = ensure_numeric(line1, numpy.float)   
    81 
    82     x0 = line0[0,0]; y0 = line0[0,1]
    83     x1 = line0[1,0]; y1 = line0[1,1]
    84 
    85     x2 = line1[0,0]; y2 = line1[0,1]
    86     x3 = line1[1,0]; y3 = line1[1,1]
    87 
    88     denom = (y3-y2)*(x1-x0) - (x3-x2)*(y1-y0)
    89     u0 = (x3-x2)*(y0-y2) - (y3-y2)*(x0-x2)
    90     u1 = (x2-x0)*(y1-y0) - (y2-y0)*(x1-x0)
    91        
    92     if numpy.allclose(denom, 0.0):
    93         # Lines are parallel - check if they coincide on a shared a segment
    94 
    95         if numpy.allclose( [u0, u1], 0.0 ):
    96             # We now know that the lines if continued coincide
    97             # The remaining check will establish if the finite lines share a segment
    98 
    99             line0_starts_on_line1 = line0_ends_on_line1 =\
    100             line1_starts_on_line0 = line1_ends_on_line0 = False
    101                
    102             if point_on_line([x0, y0], line1):
    103                 line0_starts_on_line1 = True
    104 
    105             if point_on_line([x1, y1], line1):
    106                 line0_ends_on_line1 = True
    107  
    108             if point_on_line([x2, y2], line0):
    109                 line1_starts_on_line0 = True
    110 
    111             if point_on_line([x3, y3], line0):
    112                 line1_ends_on_line0 = True                               
    113 
    114             if not(line0_starts_on_line1 or line0_ends_on_line1\
    115                or line1_starts_on_line0 or line1_ends_on_line0):
    116                 # Lines are parallel and would coincide if extended, but not as they are.
    117                 return 3, None
    118 
    119 
    120             # One line fully included in the other. Use direction of included line
    121             if line0_starts_on_line1 and line0_ends_on_line1:
    122                 # Shared segment is line0 fully included in line1
    123                 segment = numpy.array([[x0, y0], [x1, y1]])               
    124 
    125             if line1_starts_on_line0 and line1_ends_on_line0:
    126                 # Shared segment is line1 fully included in line0
    127                 segment = numpy.array([[x2, y2], [x3, y3]])
    128            
    129 
    130             # Overlap with lines are oriented the same way
    131             if line0_starts_on_line1 and line1_ends_on_line0:
    132                 # Shared segment from line0 start to line 1 end
    133                 segment = numpy.array([[x0, y0], [x3, y3]])
    134 
    135             if line1_starts_on_line0 and line0_ends_on_line1:
    136                 # Shared segment from line1 start to line 0 end
    137                 segment = numpy.array([[x2, y2], [x1, y1]])                               
    138 
    139 
    140             # Overlap in opposite directions - use direction of line0
    141             if line0_starts_on_line1 and line1_starts_on_line0:
    142                 # Shared segment from line0 start to line 1 end
    143                 segment = numpy.array([[x0, y0], [x2, y2]])
    144 
    145             if line0_ends_on_line1 and line1_ends_on_line0:
    146                 # Shared segment from line0 start to line 1 end
    147                 segment = numpy.array([[x3, y3], [x1, y1]])               
    148 
    149                
    150             return 2, segment
    151         else:
    152             # Lines are parallel but they don't coincide
    153             return 4, None #FIXME (Ole): Add distance here instead of None
    154            
    155     else:
    156         # Lines are not parallel or coinciding
    157         u0 = u0/denom
    158         u1 = u1/denom       
    159 
    160         x = x0 + u0*(x1-x0)
    161         y = y0 + u0*(y1-y0)
    162 
    163         # Sanity check - can be removed to speed up if needed
    164         assert numpy.allclose(x, x2 + u1*(x3-x2))
    165         assert numpy.allclose(y, y2 + u1*(y3-y2))       
    166 
    167         # Check if point found lies within given line segments
    168         if 0.0 <= u0 <= 1.0 and 0.0 <= u1 <= 1.0:
    169             # We have intersection
    170 
    171             return 1, numpy.array([x, y])
    172         else:
    173             # No intersection
    174             return 0, None
    175 
    176 
    177 def NEW_C_intersection(line0, line1):
    178     #FIXME(Ole): To write in C
    179     """Returns intersecting point between two line segments or None
    180     (if parallel or no intersection is found).
    181 
    182     However, if parallel lines coincide partly (i.e. shara a common segment,
    183     the line segment where lines coincide is returned
    184    
    185 
    186     Inputs:
    187         line0, line1: Each defined by two end points as in: [[x0, y0], [x1, y1]]
    188                       A line can also be a 2x2 numeric array with each row
    189                       corresponding to a point.
    190 
    191 
    192     Output:
    193         status, value
    194 
    195         where status is interpreted as follows
    196        
    197         status == 0: no intersection with value set to None
    198         status == 1: One intersection point found and returned in value as [x,y]
    199         status == 2: Coinciding line segment found. Value taks the form [[x0,y0], [x1,y1]]
    200         status == 3: Lines would coincide but only if extended. Value set to None
    201         status == 4: Lines are parallel with a fixed distance apart. Value set to None.
    202    
    203     """
    204 
    205 
    206     line0 = ensure_numeric(line0, numpy.float)
    207     line1 = ensure_numeric(line1, numpy.float)   
     184
     185    line0 = ensure_numeric(line0, Float)
     186    line1 = ensure_numeric(line1, Float)   
    208187
    209188    status, value = _intersection(line0[0,0], line0[0,1],
     
    313292    #if verbose: print 'Checking input to outside_polygon'
    314293    try:
    315         points = ensure_numeric(points, numpy.float)
     294        points = ensure_numeric(points, Float)
    316295    except NameError, e:
    317296        raise NameError, e
     
    321300
    322301    try:
    323         polygon = ensure_numeric(polygon, numpy.float)
     302        polygon = ensure_numeric(polygon, Float)
    324303    except NameError, e:
    325304        raise NameError, e
     
    355334    #if verbose: print 'Checking input to outside_polygon'
    356335    try:
    357         points = ensure_numeric(points, numpy.float)
     336        points = ensure_numeric(points, Float)
    358337    except NameError, e:
    359338        raise NameError, e
     
    363342
    364343    try:
    365         polygon = ensure_numeric(polygon, numpy.float)
     344        polygon = ensure_numeric(polygon, Float)
    366345    except NameError, e:
    367346        raise NameError, e
     
    442421##    print 'Before: points=%s, flags=%s' % (type(points), str(points.flags))
    443422    try:
    444 ##        points = numpy.ascontiguousarray(ensure_numeric(points, numpy.float))
    445         points = ensure_numeric(points, numpy.float)
     423##        points = numpy.ascontiguousarray(ensure_numeric(points, Float))
     424        points = ensure_numeric(points, Float)
    446425    except NameError, e:
    447426        raise NameError, e
     
    453432    #if verbose: print 'Checking input to separate_points_by_polygon 2'
    454433    try:
    455 ##        polygon = numpy.ascontiguousarray(ensure_numeric(polygon, numpy.float))
    456         polygon = ensure_numeric(polygon, numpy.float)
     434##        polygon = numpy.ascontiguousarray(ensure_numeric(polygon, Float))
     435        polygon = ensure_numeric(polygon, Float)
    457436    except NameError, e:
    458437        raise NameError, e
     
    495474
    496475
    497     indices = numpy.zeros( M, numpy.int )
     476    indices = numpy.zeros( M, Int )
    498477
    499478    count = _separate_points_by_polygon(points, polygon, indices,
     
    622601
    623602    try:
    624         polygon = ensure_numeric(polygon, numpy.float)
     603        polygon = ensure_numeric(polygon, Float)
    625604    except NameError, e:
    626605        raise NameError, e
     
    733712
    734713    def __call__(self, x, y):
    735         x = numpy.array(x).astype(numpy.float)
    736         y = numpy.array(y).astype(numpy.float)
     714        x = numpy.array(x).astype(Float)
     715        y = numpy.array(y).astype(Float)
    737716
    738717        assert len(x.shape) == 1 and len(y.shape) == 1
     
    746725            z = self.default(x, y)
    747726        else:
    748             z = numpy.ones(N, numpy.float) * self.default
     727            z = numpy.ones(N, Float) * self.default
    749728
    750729        for polygon, value in self.regions:
  • anuga_core/source_numpy_conversion/anuga/utilities/test_all.py

    r2766 r5948  
    7878if __name__ == '__main__':
    7979
    80     from os import sep
     80    #from os import sep
    8181
    8282    #Attempt to compile all extensions
  • anuga_core/source_numpy_conversion/anuga/utilities/test_polygon.py

    r5902 r5948  
    658658        assert numpy.allclose(value, [1.0, 1.0])       
    659659       
     660    # This function is a helper function for
     661    # the test_intersection_bug_20081110_?() set of tests.
     662    # This function tests all parallel line cases for 4 collinear points.
     663    # This function should never be run directly by the unittest code.
     664    def helper_test_parallel_intersection_code(self, P1, P2, P3, P4):
     665        # lines in same direction, no overlap
     666        # 0:         ---->----
     667        # 1:                     --------->-----------
     668        line0 = [P1,P2]
     669        line1 = [P3,P4]
     670        status, value = intersection(line0, line1)
     671        self.failIf(status!=3, 'Expected status 3, got status=%s, value=%s' %
     672                               (str(status), str(value)))
     673        self.failUnless(value is None, 'Expected value of None, got %s' %
     674                                       str(value))
     675
     676        # lines in same direction, no overlap
     677        # 0:         ----<----
     678        # 1:                     ---------<-----------
     679        line0 = [P2,P1]
     680        line1 = [P4,P3]
     681        status, value = intersection(line0, line1)
     682        self.failIf(status!=3, 'Expected status 3, got status=%s, value=%s' %
     683                               (str(status), str(value)))
     684        self.failUnless(value is None, 'Expected value of None, got %s' %
     685                                       str(value))
     686
     687        # lines in opposite direction, no overlap
     688        # 0:         ----<----
     689        # 1:                     --------->-----------
     690        line0 = [P2,P1]
     691        line1 = [P3,P4]
     692        status, value = intersection(line0, line1)
     693        self.failIf(status!=3, 'Expected status 3, got status=%s, value=%s' %
     694                               (str(status), str(value)))
     695        self.failUnless(value is None, 'Expected value of None, got %s' %
     696                                       str(value))
     697
     698        # lines in opposite direction, no overlap
     699        # 0:         ---->----
     700        # 1:                     ---------<-----------
     701        line0 = [P1,P2]
     702        line1 = [P4,P3]
     703        status, value = intersection(line0, line1)
     704        self.failIf(status!=3, 'Expected status 3, got status=%s, value=%s' %
     705                               (str(status), str(value)))
     706        self.failUnless(value is None, 'Expected value of None, got %s' %
     707                                       str(value))
     708
     709        #----------------------------------------------------------------------
     710
     711        # line0 fully within line1, same direction
     712        # 0:         ---->----
     713        # 1:    --------->-----------
     714        # value should be line0:
     715        #            ---->----
     716        line0 = [P2,P3]
     717        line1 = [P1,P4]
     718        status, value = intersection(line0, line1)
     719        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     720                               (str(status), str(value)))
     721        self.failUnless(numpy.allclose(value, line0))
     722
     723        # line0 fully within line1, same direction
     724        # 0:         ----<----
     725        # 1:    ---------<-----------
     726        # value should be line0:
     727        #            ----<----
     728        line0 = [P3,P2]
     729        line1 = [P4,P1]
     730        status, value = intersection(line0, line1)
     731        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     732                               (str(status), str(value)))
     733        self.failUnless(numpy.allclose(value, line0))
     734
     735        # line0 fully within line1, opposite direction
     736        # 0:         ----<----
     737        # 1:    --------->-----------
     738        # value should be line0:
     739        #            ----<----
     740        line0 = [P3,P2]
     741        line1 = [P1,P4]
     742        status, value = intersection(line0, line1)
     743        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     744                               (str(status), str(value)))
     745        self.failUnless(numpy.allclose(value, line0))
     746
     747        # line0 fully within line1, opposite direction
     748        # 0:         ---->----
     749        # 1:    ---------<-----------
     750        # value should be line0:
     751        #            ---->----
     752        line0 = [P2,P3]
     753        line1 = [P4,P1]
     754        status, value = intersection(line0, line1)
     755        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     756                               (str(status), str(value)))
     757        self.failUnless(numpy.allclose(value, line0))
     758
     759        #----------------------------------------------------------------------
     760
     761        # line1 fully within line0, same direction
     762        # 0:    --------->-----------
     763        # 1:         ---->----
     764        # value should be line1:
     765        #            ---->----
     766        line0 = [P1,P4]
     767        line1 = [P2,P3]
     768        status, value = intersection(line0, line1)
     769        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     770                               (str(status), str(value)))
     771        self.failUnless(numpy.allclose(value, line1))
     772
     773        # line1 fully within line0, same direction
     774        # 0:    ---------<-----------
     775        # 1:         ----<----
     776        # value should be line1:
     777        #            ----<----
     778        line0 = [P4,P1]
     779        line1 = [P3,P2]
     780        status, value = intersection(line0, line1)
     781        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     782                               (str(status), str(value)))
     783        self.failUnless(numpy.allclose(value, line1))
     784
     785        # line1 fully within line0, opposite direction
     786        # 0:    ---------<-----------
     787        # 1:         ---->----
     788        # value should be line1:
     789        #            ---->----
     790        line0 = [P4,P1]
     791        line1 = [P2,P3]
     792        status, value = intersection(line0, line1)
     793        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     794                               (str(status), str(value)))
     795        self.failUnless(numpy.allclose(value, line1))
     796
     797        # line1 fully within line0, opposite direction
     798        # 0:    --------->-----------
     799        # 1:         ----<----
     800        # value should be line1:
     801        #            ----<----
     802        line0 = [P1,P4]
     803        line1 = [P3,P2]
     804        status, value = intersection(line0, line1)
     805        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     806                               (str(status), str(value)))
     807        self.failUnless(numpy.allclose(value, line1))
     808
     809        #----------------------------------------------------------------------
     810
     811        # line in same direction, partial overlap
     812        # 0:    ----->-----
     813        # 1:       ------->--------
     814        # value should be segment line1_start->line0_end:
     815        #          --->----
     816        line0 = [P1,P3]
     817        line1 = [P2,P4]
     818        status, value = intersection(line0, line1)
     819        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     820                               (str(status), str(value)))
     821        self.failUnless(numpy.allclose(value, [line1[0],line0[1]]))
     822
     823        # line in same direction, partial overlap
     824        # 0:    -----<-----
     825        # 1:       -------<--------
     826        # value should be segment line0_start->line1_end:
     827        #          ---<----
     828        line0 = [P3,P1]
     829        line1 = [P4,P2]
     830        status, value = intersection(line0, line1)
     831        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     832                               (str(status), str(value)))
     833        self.failUnless(numpy.allclose(value, [line0[0],line1[1]]))
     834
     835        # line in opposite direction, partial overlap
     836        # 0:    -----<-----
     837        # 1:       ------->--------
     838        # value should be segment line0_start->line1_start:
     839        #          ---<----
     840        line0 = [P3,P1]
     841        line1 = [P2,P4]
     842        status, value = intersection(line0, line1)
     843        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     844                               (str(status), str(value)))
     845        self.failUnless(numpy.allclose(value, [line0[0],line1[0]]))
     846
     847        # line in opposite direction, partial overlap
     848        # 0:    ----->-----
     849        # 1:       -------<--------
     850        # value should be segment line1_end->line0_end:
     851        #          --->----
     852        line0 = [P1,P3]
     853        line1 = [P4,P2]
     854        status, value = intersection(line0, line1)
     855        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     856                               (str(status), str(value)))
     857        self.failUnless(numpy.allclose(value, [line1[1],line0[1]]))
     858
     859        #----------------------------------------------------------------------
     860
     861        # line in same direction, partial overlap
     862        # 0:       ------>------
     863        # 1:    ------>------
     864        # value should be segment line0_start->line1_end:
     865        #          --->----
     866        line0 = [P2,P4]
     867        line1 = [P1,P3]
     868        status, value = intersection(line0, line1)
     869        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     870                               (str(status), str(value)))
     871        self.failUnless(numpy.allclose(value, [line0[0],line1[1]]))
     872
     873        # line in same direction, partial overlap
     874        # 0:       ------<------
     875        # 1:    ------<------
     876        # value should be segment line1_start->line0_end:
     877        #          ----<-----
     878        line0 = [P4,P2]
     879        line1 = [P3,P1]
     880        status, value = intersection(line0, line1)
     881        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     882                               (str(status), str(value)))
     883        self.failUnless(numpy.allclose(value, [line1[0],line0[1]]))
     884
     885        # line in opposite direction, partial overlap
     886        # 0:       ------<------
     887        # 1:    ----->------
     888        # value should be segment line1_end->line0_end:
     889        #          --->----
     890        line0 = [P4,P2]
     891        line1 = [P1,P3]
     892        status, value = intersection(line0, line1)
     893        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     894                               (str(status), str(value)))
     895        self.failUnless(numpy.allclose(value, [line1[1],line0[1]]))
     896
     897        # line in opposite direction, partial overlap
     898        # 0:       ------>------
     899        # 1:    -----<------
     900        # value should be segment line0_start->line1_start:
     901        #          ---<----
     902        line0 = [P2,P4]
     903        line1 = [P3,P1]
     904        status, value = intersection(line0, line1)
     905        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     906                               (str(status), str(value)))
     907        self.failUnless(numpy.allclose(value, [line0[0],line1[0]]))
     908
     909        #----------------------------------------------------------------------
     910
     911        # line in same direction, same left point, line1 longer
     912        # 0:    ----->------
     913        # 1:    ------->--------
     914        # value should be line0:
     915        #       ----->------
     916        line0 = [P1,P3]
     917        line1 = [P1,P4]
     918        status, value = intersection(line0, line1)
     919        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     920                               (str(status), str(value)))
     921        self.failUnless(numpy.allclose(value, line0))
     922
     923        # line in same direction, same left point, line1 longer
     924        # 0:    -----<------
     925        # 1:    -------<--------
     926        # value should be line0:
     927        #       -----<------
     928        line0 = [P3,P1]
     929        line1 = [P4,P1]
     930        status, value = intersection(line0, line1)
     931        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     932                               (str(status), str(value)))
     933        self.failUnless(numpy.allclose(value, line0))
     934
     935        # line in opposite direction, same left point, line1 longer
     936        # 0:    ----->------
     937        # 1:    -------<--------
     938        # value should be line0:
     939        #       ----->------
     940        line0 = [P1,P3]
     941        line1 = [P4,P1]
     942        status, value = intersection(line0, line1)
     943        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     944                               (str(status), str(value)))
     945        self.failUnless(numpy.allclose(value, line0))
     946
     947        # line in opposite direction, same start point, line1 longer
     948        # 0:    -----<------
     949        # 1:    ------->--------
     950        # value should be line0:
     951        #       -----<------
     952        line0 = [P3,P1]
     953        line1 = [P1,P4]
     954        status, value = intersection(line0, line1)
     955        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     956                               (str(status), str(value)))
     957        self.failUnless(numpy.allclose(value, line0))
     958
     959        #----------------------------------------------------------------------
     960
     961        # line in same direction, same left point, same right point
     962        # 0:    ------->--------
     963        # 1:    ------->--------
     964        # value should be line0 or line1:
     965        #       ------->--------
     966        line0 = [P1,P3]
     967        line1 = [P1,P3]
     968        status, value = intersection(line0, line1)
     969        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     970                               (str(status), str(value)))
     971        self.failUnless(numpy.allclose(value, line0))
     972
     973        # line in same direction, same left point, same right point
     974        # 0:    -------<--------
     975        # 1:    -------<--------
     976        # value should be line0 (or line1):
     977        #       -------<--------
     978        line0 = [P3,P1]
     979        line1 = [P3,P1]
     980        status, value = intersection(line0, line1)
     981        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     982                               (str(status), str(value)))
     983        self.failUnless(numpy.allclose(value, line0))
     984
     985        # line in opposite direction, same left point, same right point
     986        # 0:    ------->--------
     987        # 1:    -------<--------
     988        # value should be line0:
     989        #       ------->--------
     990        line0 = [P1,P3]
     991        line1 = [P3,P1]
     992        status, value = intersection(line0, line1)
     993        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     994                               (str(status), str(value)))
     995        self.failUnless(numpy.allclose(value, line0))
     996
     997        # line in opposite direction, same left point, same right point
     998        # 0:    -------<--------
     999        # 1:    ------->--------
     1000        # value should be line0:
     1001        #       -------<--------
     1002        line0 = [P3,P1]
     1003        line1 = [P1,P3]
     1004        status, value = intersection(line0, line1)
     1005        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1006                               (str(status), str(value)))
     1007        self.failUnless(numpy.allclose(value, line0))
     1008
     1009        #----------------------------------------------------------------------
     1010
     1011        # line in same direction, same right point, line1 longer
     1012        # 0:        ----->------
     1013        # 1:    ------->--------
     1014        # value should be line0:
     1015        #           ----->------
     1016        line0 = [P2,P4]
     1017        line1 = [P1,P4]
     1018        status, value = intersection(line0, line1)
     1019        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1020                               (str(status), str(value)))
     1021        self.failUnless(numpy.allclose(value, line0))
     1022
     1023        # line in same direction, same right point, line1 longer
     1024        # 0:        -----<------
     1025        # 1:    -------<--------
     1026        # value should be line0:
     1027        #           -----<------
     1028        line0 = [P4,P2]
     1029        line1 = [P4,P1]
     1030        status, value = intersection(line0, line1)
     1031        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1032                               (str(status), str(value)))
     1033        self.failUnless(numpy.allclose(value, line0))
     1034
     1035        # line in opposite direction, same right point, line1 longer
     1036        # 0:        ----->------
     1037        # 1:    -------<--------
     1038        # value should be line0:
     1039        #           ----->------
     1040        line0 = [P2,P4]
     1041        line1 = [P4,P1]
     1042        status, value = intersection(line0, line1)
     1043        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1044                               (str(status), str(value)))
     1045        self.failUnless(numpy.allclose(value, line0))
     1046
     1047        # line in opposite direction, same right point, line1 longer
     1048        # 0:        -----<------
     1049        # 1:    ------->--------
     1050        # value should be line0:
     1051        #           -----<------
     1052        line0 = [P4,P2]
     1053        line1 = [P1,P4]
     1054        status, value = intersection(line0, line1)
     1055        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1056                               (str(status), str(value)))
     1057        self.failUnless(numpy.allclose(value, line0))
     1058
     1059        #----------------------------------------------------------------------
     1060
     1061        # line in same direction, same left point, line0 longer
     1062        # 0:    ------->--------
     1063        # 1:    ----->------
     1064        # value should be line1:
     1065        #       ----->------
     1066        line0 = [P1,P4]
     1067        line1 = [P1,P3]
     1068        status, value = intersection(line0, line1)
     1069        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1070                               (str(status), str(value)))
     1071        self.failUnless(numpy.allclose(value, line1))
     1072
     1073        # line in same direction, same left point, line0 longer
     1074        # 0:    -------<--------
     1075        # 1:    -----<------
     1076        # value should be line1:
     1077        #       -----<------
     1078        line0 = [P4,P1]
     1079        line1 = [P3,P1]
     1080        status, value = intersection(line0, line1)
     1081        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1082                               (str(status), str(value)))
     1083        self.failUnless(numpy.allclose(value, line1))
     1084
     1085        # line in opposite direction, same left point, line0 longer
     1086        # 0:    ------->--------
     1087        # 1:    -----<------
     1088        # value should be line1:
     1089        #       -----<------
     1090        line0 = [P1,P4]
     1091        line1 = [P3,P1]
     1092        status, value = intersection(line0, line1)
     1093        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1094                               (str(status), str(value)))
     1095        self.failUnless(numpy.allclose(value, line1))
     1096
     1097        # line in opposite direction, same left point, line0 longer
     1098        # 0:    -------<--------
     1099        # 1:    ----->------
     1100        # value should be line1:
     1101        #       ----->------
     1102        line0 = [P4,P1]
     1103        line1 = [P1,P3]
     1104        status, value = intersection(line0, line1)
     1105        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1106                               (str(status), str(value)))
     1107        self.failUnless(numpy.allclose(value, line1))
     1108
     1109        #----------------------------------------------------------------------
     1110
     1111        # line in same direction, same right point, line0 longer
     1112        # 0:    ------->--------
     1113        # 1:        ----->------
     1114        # value should be line1:
     1115        #           ----->------
     1116        line0 = [P1,P4]
     1117        line1 = [P2,P4]
     1118        status, value = intersection(line0, line1)
     1119        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1120                               (str(status), str(value)))
     1121        self.failUnless(numpy.allclose(value, line1))
     1122
     1123        # line in same direction, same right point, line0 longer
     1124        # 0:    -------<--------
     1125        # 1:        -----<------
     1126        # value should be line1:
     1127        #           -----<------
     1128        line0 = [P4,P1]
     1129        line1 = [P4,P2]
     1130        status, value = intersection(line0, line1)
     1131        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1132                               (str(status), str(value)))
     1133        self.failUnless(numpy.allclose(value, line1))
     1134
     1135        # line in opposite direction, same right point, line0 longer
     1136        # 0:    ------->--------
     1137        # 1:        -----<------
     1138        # value should be line1:
     1139        #           -----<------
     1140        line0 = [P1,P4]
     1141        line1 = [P4,P2]
     1142        status, value = intersection(line0, line1)
     1143        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1144                               (str(status), str(value)))
     1145        self.failUnless(numpy.allclose(value, line1))
     1146
     1147        # line in opposite direction, same right point, line0 longer
     1148        # 0:    -------<--------
     1149        # 1:        ----->------
     1150        # value should be line1:
     1151        #           ----->------
     1152        line0 = [P4,P1]
     1153        line1 = [P2,P4]
     1154        status, value = intersection(line0, line1)
     1155        self.failIf(status!=2, 'Expected status 2, got status=%s, value=%s' %
     1156                               (str(status), str(value)))
     1157        self.failUnless(numpy.allclose(value, line1))
     1158
     1159       
     1160    def test_intersection_bug_20081110_TR(self):
     1161        """test_intersection_bug_20081110(self)
     1162
     1163        Test all cases in top-right quadrant
     1164        """
     1165
     1166        # define 4 collinear points in top-right quadrant
     1167        #    P1---P2---P3---P4
     1168        P1 = [1.0, 1.0]
     1169        P2 = [2.0, 2.0]
     1170        P3 = [3.0, 3.0]
     1171        P4 = [4.0, 4.0]
     1172       
     1173        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1174        P1 = [1.0, 1.0+1.0e-9]
     1175        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1176        P1 = [1.0, 1.0]
     1177        P2 = [2.0, 2.0+1.0e-9]
     1178        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1179        P2 = [2.0, 2.0]
     1180        P3 = [3.0, 3.0+1.0e-9]
     1181        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1182        P3 = [3.0, 3.0]
     1183        P4 = [4.0, 4.0+1.0e-9]
     1184        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1185
     1186    def test_intersection_bug_20081110_TL(self):
     1187        """test_intersection_bug_20081110(self)
     1188
     1189        Test all cases in top-left quadrant
     1190        """
     1191
     1192        # define 4 collinear points in top-left quadrant
     1193        #    P1---P2---P3---P4
     1194        P1 = [-1.0, 1.0]
     1195        P2 = [-2.0, 2.0]
     1196        P3 = [-3.0, 3.0]
     1197        P4 = [-4.0, 4.0]
     1198       
     1199        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1200        P1 = [-1.0, 1.0+1.0e-9]
     1201        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1202        P1 = [-1.0, 1.0]
     1203        P2 = [-2.0, 2.0+1.0e-9]
     1204        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1205        P2 = [-2.0, 2.0]
     1206        P3 = [-3.0, 3.0+1.0e-9]
     1207        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1208        P3 = [-3.0, 3.0]
     1209        P4 = [-4.0, 4.0+1.0e-9]
     1210        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1211
     1212    def test_intersection_bug_20081110_BL(self):
     1213        """test_intersection_bug_20081110(self)
     1214
     1215        Test all cases in bottom-left quadrant
     1216        """
     1217
     1218        # define 4 collinear points in bottom-left quadrant
     1219        #    P1---P2---P3---P4
     1220        P1 = [-1.0, -1.0]
     1221        P2 = [-2.0, -2.0]
     1222        P3 = [-3.0, -3.0]
     1223        P4 = [-4.0, -4.0]
     1224       
     1225        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1226        P1 = [-1.0, -1.0+1.0e-9]
     1227        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1228        P1 = [-1.0, -1.0]
     1229        P2 = [-2.0, -2.0+1.0e-9]
     1230        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1231        P2 = [-2.0, -2.0]
     1232        P3 = [-3.0, -3.0+1.0e-9]
     1233        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1234        P3 = [-3.0, -3.0]
     1235        P4 = [-4.0, -4.0+1.0e-9]
     1236        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1237
     1238    def test_intersection_bug_20081110_BR(self):
     1239        """test_intersection_bug_20081110(self)
     1240
     1241        Test all cases in bottom-right quadrant
     1242        """
     1243
     1244        # define 4 collinear points in bottom-right quadrant
     1245        #    P1---P2---P3---P4
     1246        P1 = [1.0, -1.0]
     1247        P2 = [2.0, -2.0]
     1248        P3 = [3.0, -3.0]
     1249        P4 = [4.0, -4.0]
     1250       
     1251        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1252        P1 = [1.0, -1.0+1.0e-9]
     1253        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1254        P1 = [1.0, -1.0]
     1255        P2 = [2.0, -2.0+1.0e-9]
     1256        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1257        P2 = [2.0, -2.0]
     1258        P3 = [3.0, -3.0+1.0e-9]
     1259        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1260        P3 = [3.0, -3.0]
     1261        P4 = [4.0, -4.0+1.0e-9]
     1262        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)       
     1263
     1264    def test_intersection_bug_20081110_TR_TL(self):
     1265        """test_intersection_bug_20081110(self)
     1266
     1267        Test all cases in top-right & top-left quadrant
     1268        """
     1269
     1270        # define 4 collinear points, 1 in TL, 3 in TR
     1271        #    P1---P2---P3---P4
     1272        P1 = [-3.0, 1.0]
     1273        P2 = [ 1.0, 5.0]
     1274        P3 = [ 2.0, 6.0]
     1275        P4 = [ 3.0, 7.0]
     1276        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1277
     1278        # define 4 collinear points, 2 in TL, 2 in TR
     1279        #    P1---P2---P3---P4
     1280        P1 = [-3.0, 1.0]
     1281        P2 = [-2.0, 2.0]
     1282        P3 = [ 2.0, 6.0]
     1283        P4 = [ 3.0, 7.0]
     1284        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1285
     1286        # define 4 collinear points, 2 in TL, 1 in TR
     1287        #    P1---P2---P3---P4
     1288        P1 = [-3.0, 1.0]
     1289        P2 = [-2.0, 2.0]
     1290        P3 = [-1.0, 3.0]
     1291        P4 = [ 3.0, 7.0]
     1292        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1293
     1294    def test_intersection_bug_20081110_TR_BL(self):
     1295        """test_intersection_bug_20081110(self)
     1296
     1297        Test all cases in top-right & bottom-left quadrant
     1298        """
     1299
     1300        # define 4 collinear points, 1 in BL, 3 in TR
     1301        #    P1---P2---P3---P4
     1302        P1 = [-4.0, -3.0]
     1303        P2 = [ 1.0,  2.0]
     1304        P3 = [ 2.0,  3.0]
     1305        P4 = [ 3.0,  4.0]
     1306        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1307
     1308        # define 4 collinear points, 2 in TL, 2 in TR
     1309        #    P1---P2---P3---P4
     1310        P1 = [-4.0, -3.0]
     1311        P2 = [-3.0, -2.0]
     1312        P3 = [ 2.0,  3.0]
     1313        P4 = [ 3.0,  4.0]
     1314        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1315
     1316        # define 4 collinear points, 3 in TL, 1 in TR
     1317        #    P1---P2---P3---P4
     1318        P1 = [-4.0, -3.0]
     1319        P2 = [-3.0, -2.0]
     1320        P3 = [-2.0, -1.0]
     1321        P4 = [ 3.0,  4.0]
     1322        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1323
     1324    def test_intersection_bug_20081110_TR_BR(self):
     1325        """test_intersection_bug_20081110(self)
     1326
     1327        Test all cases in top-right & bottom-right quadrant
     1328        """
     1329
     1330        # define 4 collinear points, 1 in BR, 3 in TR
     1331        #    P1---P2---P3---P4
     1332        P1 = [ 1.0, -3.0]
     1333        P2 = [ 5.0,  1.0]
     1334        P3 = [ 6.0,  2.0]
     1335        P4 = [ 7.0,  3.0]
     1336        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1337
     1338        # define 4 collinear points, 2 in BR, 2 in TR
     1339        #    P1---P2---P3---P4
     1340        P1 = [ 1.0, -3.0]
     1341        P2 = [ 2.0, -2.0]
     1342        P3 = [ 6.0,  2.0]
     1343        P4 = [ 7.0,  3.0]
     1344        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1345
     1346        # define 4 collinear points, 3 in BR, 1 in TR
     1347        #    P1---P2---P3---P4
     1348        P1 = [ 1.0, -3.0]
     1349        P2 = [ 2.0, -2.0]
     1350        P3 = [ 3.0, -1.0]
     1351        P4 = [ 7.0,  3.0]
     1352        self.helper_test_parallel_intersection_code(P1, P2, P3, P4)
     1353
    6601354
    6611355    def test_intersection_direction_invariance(self):
     
    9971691if __name__ == "__main__":
    9981692    suite = unittest.makeSuite(Test_Polygon,'test')
    999 ##    suite = unittest.makeSuite(Test_Polygon,'test_polygon_function_constantsX')
     1693##    suite = unittest.makeSuite(Test_Polygon,'test_intersection_bug_20081110')
    10001694    runner = unittest.TextTestRunner()
    10011695    runner.run(suite)
Note: See TracChangeset for help on using the changeset viewer.