Ignore:
Timestamp:
Oct 3, 2006, 5:47:08 PM (18 years ago)
Author:
ole
Message:

Work on get_boundary_polygon using (discontinuous) example that fails

File:
1 edited

Legend:

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

    r3676 r3684  
    44"""
    55
     6from math import acos, pi, sqrt
     7from warnings import warn
    68
    79#Establish which Numeric package to use
     
    2123
    2224
     25def safe_acos(x):
     26    """Safely compute acos
     27
     28    Protect against cases where input argument x is outside the allowed
     29    interval [-1.0, 1.0] by no more than machine precision
     30    """
     31
     32    error_msg = 'Input to acos is outside allowed domain [-1.0, 1.0]. I got %.12f' %x
     33    warning_msg = 'Changing argument to acos from %.18f to %.1f' %(x, sign(x))
     34
     35    # FIXME(Ole): Need function to compute machine precision as this is also
     36    # used in fit_interpolate/search_functions.py
     37   
     38   
     39    eps = 1.0e-15  # Machine precision
     40    if x < -1.0:
     41        if x < -1.0 - eps:
     42            raise ValueError, errmsg
     43        else:
     44            warn(warning_msg)
     45            x = -1.0
     46
     47    if x > 1.0:
     48        if x > 1.0 + eps:
     49            raise ValueError, errmsg
     50        else:
     51            print 'NOTE: changing argument to acos from %.18f to 1.0' %x           
     52            x = 1.0
     53
     54    return acos(x)
     55
     56
     57def sign(x):
     58    if x > 0: return 1
     59    if x < 0: return -1
     60    if x == 0: return 0   
     61   
     62
    2363def angle(v1, v2=None):
    2464    """Compute angle between 2D vectors v1 and v2.
     
    2969    The angle is measured as a number in [0, 2pi] from v2 to v1.
    3070    """
    31     from math import acos, pi, sqrt
    3271 
    3372    # Prepare two Numeric vectors
     
    4180    v1 = v1/sqrt(sum(v1**2))
    4281    v2 = v2/sqrt(sum(v2**2))
    43    
     82
    4483    # Compute angle
    4584    p = innerproduct(v1, v2)
    4685    c = innerproduct(v1, normal_vector(v2)) # Projection onto normal
    4786                                            # (negative cross product)
    48     #print "p",p
    49     #print "v1", v1
    50     #print "v2", v2
    51 
    52    
    53     # Warning, this is a hack.  It could cause code to go in loop forever
    54     if False:
    55         try:
    56             theta = acos(p)
    57             #print "theta",theta
    58         except ValueError:
    59             print "Doing a hack in numerical tools."
    60             print "p",p
    61             print "v1", v1
    62             print "v2", v2
    63             if p > (1.0 - 1e-12): #sus, checking a float
    64                 # Throw a warning
    65                 theta = 0.0
    66             else:
    67                 raise
    68     else:
    69         theta = acos(p)
     87       
     88    theta = safe_acos(p)
    7089           
    71      #   print "problem with p",p
    72      # as p goes to 1 theta goes to 0
    7390   
    7491    # Correct if v1 is in quadrant 3 or 4 with respect to v2 (as the x-axis)
Note: See TracChangeset for help on using the changeset viewer.