Changeset 6535


Ignore:
Timestamp:
Mar 17, 2009, 11:06:55 PM (15 years ago)
Author:
ole
Message:

Wrote is_inside_triangle in C and tested it some more.

Location:
anuga_core/source/anuga/utilities
Files:
3 edited

Legend:

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

    r6534 r6535  
    188188def is_inside_triangle(point, triangle,
    189189                       closed=True,
    190                        rtol=1.0e-6,
    191                        atol=1.0e-8,                     
     190                       rtol=1.0e-12,
     191                       atol=1.0e-12,                     
    192192                       check_inputs=True,
    193193                       verbose=False):
     
    228228   
    229229    rtol and atol will determine how close the point has to be to the edge
    230     before it is deemed on the edge.
     230    before it is deemed to be on the edge.
    231231   
    232232    """
     
    246246    if point[1] > max(triangle[:,1]): return False       
    247247
    248    
     248    return bool(_is_inside_triangle(point, triangle, int(closed), rtol, atol))
     249   
     250   
     251
     252    # FIXME (Ole): The rest of this function has been made
     253    # obsolete by the C extension
     254       
    249255    # Start search   
    250256    A = triangle[0, :]
     
    282288                                 Y[0], Y[1],
    283289                                 rtol, atol)
     290           
    284291            if res:
    285292                return True
    286293               
    287                
     294    return False
    288295
    289296
     
    12331240    from polygon_ext import _separate_points_by_polygon
    12341241    from polygon_ext import _interpolate_polyline   
     1242    from polygon_ext import _is_inside_triangle       
    12351243    #from polygon_ext import _intersection
    12361244
  • anuga_core/source/anuga/utilities/polygon_ext.c

    r6534 r6535  
    244244
    245245
     246
     247int __is_inside_triangle(double* point,
     248                         double* triangle,
     249                         int closed,
     250                         double rtol,
     251                         double atol) {
     252                         
     253  double vx, vy, v0x, v0y, v1x, v1y;
     254  double a00, a10, a01, a11, b0, b1;
     255  double denom, alpha, beta;
     256  int i, j, res;
     257
     258  // v0 = C-A
     259  v0x = triangle[4]-triangle[0];
     260  v0y = triangle[5]-triangle[1];
     261 
     262  // v1 = B-A   
     263  v1x = triangle[2]-triangle[0];
     264  v1y = triangle[3]-triangle[1];
     265
     266  // First check if point lies wholly inside triangle
     267  a00 = v0x*v0x + v0y*v0y; // innerproduct(v0, v0)
     268  a01 = v0x*v1x + v0y*v1y; // innerproduct(v0, v1)
     269  a10 = a01;               // innerproduct(v1, v0)
     270  a11 = v1x*v1x + v1y*v1y; // innerproduct(v1, v1)
     271   
     272  denom = a11*a00 - a01*a10;
     273
     274  if (fabs(denom) > 0.0) {
     275    // v = point-A 
     276    vx = point[0] - triangle[0];
     277    vy = point[1] - triangle[1];     
     278   
     279    b0 = v0x*vx + v0y*vy; // innerproduct(v0, v)       
     280    b1 = v1x*vx + v1y*vy; // innerproduct(v1, v)           
     281   
     282    alpha = (b0*a11 - b1*a01)/denom;
     283    beta = (b1*a00 - b0*a10)/denom;       
     284   
     285    if ((alpha > 0.0) && (beta > 0.0) && (alpha+beta < 1.0)) return 1;
     286  }
     287
     288  if (closed) {
     289    // Check if point lies on one of the edges
     290       
     291    for (i=0; i<3; i++) {
     292      j = (i+1) % 3; // Circular index into triangle array
     293      res = __point_on_line(point[0], point[1],
     294                            triangle[2*i], triangle[2*i+1],
     295                            triangle[2*j], triangle[2*j+1],                         
     296                            rtol, atol);
     297      if (res) return 1;
     298    }
     299  }
     300               
     301  // Default return if point is outside triangle                         
     302  return 0;                                             
     303}                                                                             
     304
     305
    246306int __separate_points_by_polygon(int M,     // Number of points
    247307                                 int N,     // Number of polygon vertices
     
    255315  int i, j, k, outside_index, inside_index, inside;
    256316
    257   //Find min and max of poly used for optimisation when points
    258   //are far away from polygon
    259  
    260   //FIXME(Ole): Pass in rtol and atol from Python
     317  // Find min and max of poly used for optimisation when points
     318  // are far away from polygon
     319 
     320  // FIXME(Ole): Pass in rtol and atol from Python
    261321
    262322  minpx = polygon[0]; maxpx = minpx;
     
    273333  }
    274334
    275   //Begin main loop (for each point)
    276   inside_index = 0;    //Keep track of points inside
    277   outside_index = M-1; //Keep track of points outside (starting from end)   
     335  // Begin main loop (for each point)
     336  inside_index = 0;    // Keep track of points inside
     337  outside_index = M-1; // Keep track of points outside (starting from end)   
    278338  if (verbose){
    279339     printf("Separating %d points\n", M);
     
    289349    inside = 0;
    290350
    291     //Optimisation
     351    // Optimisation
    292352    if ((x > maxpx) || (x < minpx) || (y > maxpy) || (y < minpy)) {
    293       //Nothing
     353      // Nothing
    294354    } else {   
    295       //Check polygon
     355      // Check polygon
    296356      for (i=0; i<N; i++) {
    297         //printf("k,i=%d,%d\n", k, i);
    298357        j = (i+1)%N;
    299358
     
    303362        py_j = polygon[2*j+1];
    304363
    305         //Check for case where point is contained in line segment
     364        // Check for case where point is contained in line segment
    306365        if (__point_on_line(x, y, px_i, py_i, px_j, py_j, rtol, atol)) {
    307366          if (closed == 1) {
     
    312371          break;
    313372        } else {
    314           //Check if truly inside polygon
     373          // Check if truly inside polygon
    315374          if ( ((py_i < y) && (py_j >= y)) ||
    316375               ((py_j < y) && (py_i >= y)) ) {
     
    356415  res = __point_on_line(x, y, x0, y0, x1, y1, rtol, atol);
    357416
    358   // Return values a and b
     417  // Return result
    359418  result = Py_BuildValue("i", res);
    360419  return result;
     
    417476
    418477
     478
     479     
     480PyObject *_is_inside_triangle(PyObject *self, PyObject *args) {
     481  //
     482  // _is_inside_triangle(point, triangle, int(closed), rtol, atol)
     483  //
     484
     485 
     486  PyArrayObject
     487    *point,
     488    *triangle;
     489
     490  double rtol, atol; 
     491  int closed, res;
     492
     493  PyObject *result;
     494     
     495  // Convert Python arguments to C
     496  if (!PyArg_ParseTuple(args, "OOidd",
     497                        &point,
     498                        &triangle,
     499                        &closed,
     500                        &rtol,
     501                        &atol)) {
     502   
     503    PyErr_SetString(PyExc_RuntimeError,
     504                    "_is_inside_triangle could not parse input");
     505    return NULL;
     506  }
     507
     508  // Call underlying routine
     509  res = __is_inside_triangle((double*) point -> data,
     510                             (double*) triangle -> data,
     511                             closed,
     512                             rtol,
     513                             atol);                                                   
     514
     515
     516  // Return result
     517  result = Py_BuildValue("i", res);
     518  return result; 
     519}
     520     
     521
     522
    419523/*
    420524PyObject *_intersection(PyObject *self, PyObject *args) {
     
    539643  {"_interpolate_polyline", _interpolate_polyline,
    540644                                 METH_VARARGS, "Print out"},                             
     645  {"_is_inside_triangle", _is_inside_triangle,
     646                                 METH_VARARGS, "Print out"},
    541647  {NULL, NULL, 0, NULL}   /* sentinel */
    542648};
  • anuga_core/source/anuga/utilities/test_polygon.py

    r6534 r6535  
    18571857        assert num.allclose(z, z_ref)               
    18581858       
     1859
     1860    def test_is_inside_triangle_more(self):       
     1861       
     1862        res = is_inside_triangle([0.5, 0.5], [[ 0.5,  0. ],
     1863                                              [ 0.5,  0.5],
     1864                                              [ 0.,   0. ]])
     1865        assert res is True
     1866
     1867        res = is_inside_triangle([0.59999999999999998, 0.29999999999999999],
     1868                                 [[ 0.5,  0. ], [ 0.5, 0.5], [0., 0.]])
     1869        assert res is False
     1870       
     1871        res = is_inside_triangle([0.59999999999999998, 0.29999999999999999],
     1872                                 [[1., 0.], [1., 0.5], [0.5, 0.]])
     1873        assert res is False                                 
     1874                                 
     1875       
     1876        res = is_inside_triangle([0.59999999999999998, 0.29999999999999999],
     1877                                 [[0.5, 0.5], [0.5, 0.], [1., 0.5]])
     1878        assert res is True                                 
     1879
     1880               
     1881        res = is_inside_triangle([0.10000000000000001, 0.20000000000000001],
     1882                                 [[0.5, 0.], [0.5, 0.5], [0., 0.]])
     1883        assert res is False
     1884
     1885       
     1886        res = is_inside_triangle([0.10000000000000001, 0.20000000000000001],
     1887                                 [[0., 0.5], [0., 0.], [0.5, 0.5]])
     1888        assert res is True                                                                 
     1889                                 
     1890        res = is_inside_triangle([0.69999999999999996, 0.69999999999999996],
     1891                                 [[0.5, 0.], [0.5, 0.5], [0., 0.]])
     1892        assert res is False                                 
     1893
     1894        res = is_inside_triangle([0.59999999999999998, 0.29999999999999999],
     1895                                 [[0.25, 0.5], [0.25, 0.25], [0.5, 0.5]])
     1896        assert res is False
     1897       
    18591898       
    18601899               
Note: See TracChangeset for help on using the changeset viewer.