Example #1
0
def nearLocateMesh(xyo, IKLE, MESHX, MESHY, tree=None):
    """
   Requires the scipy.spatial and the matplotlib.tri packages to be loaded.
    - Will use already computed tree or re-create it if necessary.
    - Will use already computed neighbourhood or re-create it if necessary.
   This function return the element number for the triangle including xyo=(xo,yo)
      or -1 if the (xo,yo) is outside the mesh
   Return: the element, the barycentric weights, and the tree and the neighbourhood if computed
   """
    # ~~> Create the KDTree of the iso-barycentres
    if tree == None:
        isoxy = np.column_stack((np.sum(MESHX[IKLE], axis=1) / 3.0,
                                 np.sum(MESHY[IKLE], axis=1) / 3.0))
        tree = cKDTree(isoxy)
    # ~~> Find the indices corresponding to the nearest elements to the points
    inear = -1
    for d, i in zip(*tree.query(xyo, 8)):
        ax, bx, cx = MESHX[IKLE[i]]
        ay, by, cy = MESHY[IKLE[i]]
        w = isInsideTriangle(xyo, (ax, ay), (bx, by), (cx, cy), nomatter=True)
        if w != []: return i, w, tree
        if inear < 0:
            inear = i
            dnear = d
        if dnear > d:
            inear = i
            dnear = d

    # ~~> Find the indices and weights corresponding to the element containing the point
    ax, bx, cx = MESHX[IKLE[inear]]
    ay, by, cy = MESHY[IKLE[inear]]

    return inear, isInsideTriangle(xyo, (ax, ay), (bx, by), (cx, cy),
                                   nomatter=False), tree
Example #2
0
def nearLocateMesh(xyo,IKLE,MESHX,MESHY,tree=None):
   """
   Requires the scipy.spatial and the matplotlib.tri packages to be loaded.
    - Will use already computed tree or re-create it if necessary.
    - Will use already computed neighbourhood or re-create it if necessary.
   This function return the element number for the triangle including xyo=(xo,yo)
      or -1 if the (xo,yo) is outside the mesh
   Return: the element, the barycentric weights, and the tree and the neighbourhood if computed
   """
   # ~~> Create the KDTree of the iso-barycentres
   if tree == None:
      isoxy = np.column_stack((np.sum(MESHX[IKLE],axis=1)/3.0,np.sum(MESHY[IKLE],axis=1)/3.0))
      tree = cKDTree(isoxy)
   # ~~> Find the indices corresponding to the nearest elements to the points
   inear = -1
   for d,i in zip(*tree.query(xyo,8)):
      ax,bx,cx = MESHX[IKLE[i]]
      ay,by,cy = MESHY[IKLE[i]]
      w = isInsideTriangle( xyo,(ax,ay),(bx,by),(cx,cy),nomatter=True )
      if w != []: return i,w,tree
      if inear < 0:
         inear = i
         dnear = d
      if dnear > d:
         inear = i
         dnear = d

   # ~~> Find the indices and weights corresponding to the element containing the point
   ax,bx,cx = MESHX[IKLE[inear]]
   ay,by,cy = MESHY[IKLE[inear]]

   return inear,isInsideTriangle( xyo,(ax,ay),(bx,by),(cx,cy),nomatter=False ),tree
Example #3
0
def traceRay2XY(IKLE,MESHX,MESHY,neighbours,ei,xyi,en,xyn):
   """
   This assumes that you cannot go back on your ray.
   """
   # ~~> latest addition to the ray
   ax,bx,cx = MESHX[IKLE[en]]
   ay,by,cy = MESHY[IKLE[en]]
   bi = getBarycentricWeights( xyi,(ax,ay),(bx,by),(cx,cy) )
   pnt = {'n':1, 'xy':[xyi], 'e':[en], 'b':[bi],
      'd':[np.power(xyi[0]-xyn[0],2) + np.power(xyi[1]-xyn[1],2)]}

   # ~~> convergence on distance to target xyn
   accuracy = np.power(10.0, -5+np.floor(np.log10(abs(ax+bx+cx+ay+by+cy))))
   if pnt['d'][0] < accuracy: return True,pnt

   # ~~> get the ray through to the farthest neighbouring edges
   ks = []; ds = []
   for k in [0,1,2]:
      xyj = getSegmentIntersection( (MESHX[IKLE[en][k]],MESHY[IKLE[en][k]]),(MESHX[IKLE[en][(k+1)%3]],MESHY[IKLE[en][(k+1)%3]]),xyi,xyn )
      if xyj == []: continue         # there are no intersection with that edges
      ej = neighbours[en][k]
      if ej == ei: continue          # you should not back track on your ray
      xyj = xyj[0]
      dij = np.power(xyi[0]-xyj[0],2) + np.power(xyi[1]-xyj[1],2)
      ks.append(k)
      ds.append(dij)
   if ds != []:
      k = ks[np.argmax(ds)]
      ej = neighbours[en][k]
      xyj = getSegmentIntersection( (MESHX[IKLE[en][k]],MESHY[IKLE[en][k]]),(MESHX[IKLE[en][(k+1)%3]],MESHY[IKLE[en][(k+1)%3]]),xyi,xyn )[0]
      djn = np.power(xyn[0]-xyj[0],2) + np.power(xyn[1]-xyj[1],2)

      # ~~> Possible recursive call
      if True or djn > accuracy:    # /!\ this may be a problem
         if ej < 0:
            # you have reach the end of the line
            bj = getBarycentricWeights( xyj,(ax,ay),(bx,by),(cx,cy) )
            pnt['n'] += 1; pnt['xy'].insert(0,xyj); pnt['e'].insert(0,en); pnt['b'].insert(0,bj); pnt['d'].insert(0,djn)
            return djn<accuracy,pnt
         else:
            found,ray = traceRay2XY(IKLE,MESHX,MESHY,neighbours,en,xyj,ej,xyn)
            ray['n'] += 1; ray['xy'].append(xyi); ray['e'].append(en); ray['b'].append(bi); ray['d'].append(dij)
            return found,ray

   # ~~> convergence on having found the appropriate triangle
   bn = isInsideTriangle( xyn,(ax,ay),(bx,by),(cx,cy) )
   if bn != []:
      pnt['n'] += 1; pnt['xy'].insert(0,xyn); pnt['e'].insert(0,en); pnt['b'].insert(0,bn); pnt['d'].insert(0,0.0)
      return True,pnt

   # ~~> you should not be here !
   return False,pnt
Example #4
0
def traceRay2XY(IKLE, MESHX, MESHY, neighbours, ei, xyi, en, xyn):
    """
   This assumes that you cannot go back on your ray.
   """
    # ~~> latest addition to the ray
    ax, bx, cx = MESHX[IKLE[en]]
    ay, by, cy = MESHY[IKLE[en]]
    bi = getBarycentricWeights(xyi, (ax, ay), (bx, by), (cx, cy))
    pnt = {
        'n': 1,
        'xy': [xyi],
        'e': [en],
        'b': [bi],
        'd': [np.power(xyi[0] - xyn[0], 2) + np.power(xyi[1] - xyn[1], 2)]
    }

    # ~~> convergence on distance to target xyn
    accuracy = np.power(
        10.0, -5 + np.floor(np.log10(abs(ax + bx + cx + ay + by + cy))))
    if pnt['d'][0] < accuracy: return True, pnt

    # ~~> get the ray through to the farthest neighbouring edges
    ks = []
    ds = []
    for k in [0, 1, 2]:
        xyj = getSegmentIntersection(
            (MESHX[IKLE[en][k]], MESHY[IKLE[en][k]]),
            (MESHX[IKLE[en][(k + 1) % 3]], MESHY[IKLE[en][(k + 1) % 3]]), xyi,
            xyn)
        if xyj == []: continue  # there are no intersection with that edges
        ej = neighbours[en][k]
        if ej == ei: continue  # you should not back track on your ray
        xyj = xyj[0]
        dij = np.power(xyi[0] - xyj[0], 2) + np.power(xyi[1] - xyj[1], 2)
        ks.append(k)
        ds.append(dij)
    if ds != []:
        k = ks[np.argmax(ds)]
        ej = neighbours[en][k]
        xyj = getSegmentIntersection(
            (MESHX[IKLE[en][k]], MESHY[IKLE[en][k]]),
            (MESHX[IKLE[en][(k + 1) % 3]], MESHY[IKLE[en][(k + 1) % 3]]), xyi,
            xyn)[0]
        djn = np.power(xyn[0] - xyj[0], 2) + np.power(xyn[1] - xyj[1], 2)

        # ~~> Possible recursive call
        if True or djn > accuracy:  # /!\ this may be a problem
            if ej < 0:
                # you have reach the end of the line
                bj = getBarycentricWeights(xyj, (ax, ay), (bx, by), (cx, cy))
                pnt['n'] += 1
                pnt['xy'].insert(0, xyj)
                pnt['e'].insert(0, en)
                pnt['b'].insert(0, bj)
                pnt['d'].insert(0, djn)
                return djn < accuracy, pnt
            else:
                found, ray = traceRay2XY(IKLE, MESHX, MESHY, neighbours, en,
                                         xyj, ej, xyn)
                ray['n'] += 1
                ray['xy'].append(xyi)
                ray['e'].append(en)
                ray['b'].append(bi)
                ray['d'].append(dij)
                return found, ray

    # ~~> convergence on having found the appropriate triangle
    bn = isInsideTriangle(xyn, (ax, ay), (bx, by), (cx, cy))
    if bn != []:
        pnt['n'] += 1
        pnt['xy'].insert(0, xyn)
        pnt['e'].insert(0, en)
        pnt['b'].insert(0, bn)
        pnt['d'].insert(0, 0.0)
        return True, pnt

    # ~~> you should not be here !
    return False, pnt