예제 #1
0
 def _linesegproj(self, qpt, p1, p2):
     """Projects the query point onto the line segment spanned by p1 and p2.
     Returns (projected pt, percentage along line p1 -> p2 (which are at 0 and 1), min dist)."""
     from nkpylib.nkutils import getTriAltitude
     # get the projection
     proj = getTriAltitude(qpt, p1, p2)
     d = -1
     for i in range(len(p1)):
         if p1[i] == p2[i]: continue # find a dimension with some change
         loc = lerp(proj[i], (p1[i], 0.0), (p2[i], 1.0))
         if loc < 0: # off the segment, closer to p1
             d = self.distfunc(qpt, p1)
             break
         if loc > 1.0: # off the segment, closer to p2
             d = self.distfunc(qpt, p2)
             break
         # valid projection, so d = its length
         d = self.distfunc(qpt, proj)
         break
     # at this point, if we didn't find any non-zero dimensions,
     # then we can pick either endpoint as our target. We set location to be None
     if d < 0:
         d = self.distfunc(qpt, p1)
         loc = None
     return (proj, loc, d)
예제 #2
0
 def interpolate(self, qi):
     """Finds the linear segment where this query index falls and interpolates values"""
     idxs = self.indexes
     i, I = self._nearestindexlocs(qi)
     if i == I: return self.pts[i] # one of the endpoints
     # index
     x, X = idxs[i], idxs[I]
     # lerp each dim of the output
     ret = self.copypt(self.pts[0])
     for dim, (y, Y) in enumerate(zip(self.pts[i], self.pts[I])):
         ret[dim] = lerp(qi, (x,y), (X,Y))
     return ret
예제 #3
0
 def project(self, qpt):
     """Projects a query point onto the closest line segment to find its equivalent index and pt.
     Returns (projected index, projected point, projection distance)"""
     mind = self.distfunc(qpt, self.pts[0])
     ret = (self.indexes[0], self.pts[0], mind)
     for p1, p2, i1, i2 in zip(self.pts, self.pts[1:], self.indexes, self.indexes[1:]):
         proj, loc, d = self._linesegproj(qpt, p1, p2)
         if d > mind: continue
         # possible candidate for best
         mind = d
         # check loc to see whether the projected point is one of the endpoints
         if loc < 0:
             # the first point
             ret = (i1, p1, d)
         elif loc > 1:
             # the 2nd point
             ret = (i2, p2, d)
         else:
             # somewhere in between
             ret = (lerp(loc, (0.0, i1), (1.0, i2)), proj, d)
     return ret