""" def find_closest_point(obj, pos): x, y, z = pos points = obj.ActivePrimitive.Geometry. Points count = points.Count points = points.PositionArray xx, yy, zz = points delta = [((x-xx[i])**2 + (y-yy[i])**2 + (z-zz[i])**2) for i in xrange(count)] return delta.index(min(delta))
""" results: # brad: 2380 in 0.0239490809458 sec. # alan: 2380 in 0.00761895761661 sec. # jojo: 2380 in 0.00452239920537 sec. 2012/5/2 Bradley Gabe <witha...@gmail.com> > Thanks Alan! You have officially leveled up and gained the title of SI > Python Optimizer (Spo). > > I knew the math, but for some reason assumed that compiled Math functions > would run faster than Python. That'll teach me. [?] Actually, thinking > about it now, anything that has to repeated call the COM layer would end up > being slow-ish. > > Nifty trick there using a key sort in lieu of comparing values to figure > out the min. > > FYI, it might be even faster for multi-Pos queries to provide an optional > 3rd argument allowing the user to input the PosArray if they have already > generated it: > > def FindClosestPoint( inObj, inPos, pos=None ): > > > fX, fY, fZ = inPos.Get2() > > if not pos: > > pts = inObj.ActivePrimitive.Geometry.Points pos = pts.PositionArray > > > d = dict( [ (i, (fX-pos[0][i])**2 + (fY-pos[1][i])**2 + (fZ-pos[2][i])**2 > ) for i in xrange(pts.Count) ] ) > closestIndices = sorted(d, key=d.get) > > # distance = d[closestIndices[0]]**0.5 > return closestIndices[0] > > > > On Wed, May 2, 2012 at 2:00 PM, Alan Fregtman <alan.fregt...@gmail.com>wrote: > >> Hey Brad, >> >> I wondered if using math directly would be faster than working with >> XSIMath objects, so I tried. You probably knew this, but to get a distance >> between two 3D vectors the formula is quite easy: >> >> * d = √ (Ax-Bx)2 + (Ay-By)2 + (Az-Bz)2 >> * >> where A and B are two vectors to measure from. >> >> However, you can skip the squareroot if you're only comparing relative >> distances. Squareroots can be computationally expensive. >> >> >> Knowing this, I wrote a version which appears to run about 77% faster, >> and it's shorter too! (It takes 4.5s testing a null near a 1000x1000 >> pointcloud grid, vs your code taking about 20.3s on the same task.) >> >> def FindClosestPoint( inObj, inPos ): >> fX, fY, fZ = inPos.Get2() >> pts = inObj.ActivePrimitive.Geometry.Points >> pos = pts.PositionArray >> >> d = dict( [ (i, (fX-pos[0][i])**2 + (fY-pos[1][i])**2 + >> (fZ-pos[2][i])**2 ) for i in xrange(pts.Count) ] ) >> closestIndices = sorted(d, key=d.get) >> >> # distance = d[closestIndices[0]]**0.5 >> return closestIndices[0] >> >> >> >> I love me a Python optimization challenge. :) >> Cheers, >> >> -- Alan >> >> >> >> ps: Friendly nod to Xavier for pointing out "**" syntax does "to the >> power of" so I don't need to use math.pow() in my code. >> >> >> On Tue, May 1, 2012 at 5:55 PM, Bradley Gabe <witha...@gmail.com> wrote: >> >>> Sure, have at it: >>> >>> def FindClosestPoint( inObj, inPos): >>> dist = 10000 >>> ID = -1 >>> Pos = XSIMath.CreateVector3() >>> PosArr = inObj.ActivePrimitive.Geometry.Points.PositionArray >>> for index in range(inObj.ActivePrimitive.Geometry.Points.Count): >>> Pos.Set( >>> PosArr[0][index], >>> PosArr[1][index], >>> PosArr[2][index] >>> ) >>> Pos.SubInPlace(inPos) >>> D = Pos.Length() >>> if D < dist: >>> dist = D >>> ID = index >>> return ID >>> >>> >>> >>> >>> On Tue, May 1, 2012 at 5:52 PM, Alan Fregtman >>> <alan.fregt...@gmail.com>wrote: >>> >>>> Care to share a sample snippet? Maybe there are even faster ways to >>>> approach it. >>>> >>>> >>>> On Tue, May 1, 2012 at 5:42 PM, Bradley Gabe <witha...@gmail.com>wrote: >>>> >>>>> UPDATE: >>>>> >>>>> All things considered, it's not too horrible simply looping through >>>>> every position from the Geometry.Points.PositionArray, and comparing the >>>>> distance in order to find the closest point in the cloud. So far, that >>>>> technique is faster than anything else I've attempted to cook up. >>>>> >>>>> -Bradley >>>>> >>>>> >>>>> On Tue, May 1, 2012 at 3:01 PM, Bradley Gabe <witha...@gmail.com>wrote: >>>>> >>>>>> Nah, it was raising errors when I tried it before starting this >>>>>> thread, and it still is now [?]: >>>>>> >>>>>> # ERROR : 2028 - Traceback (most recent call last): >>>>>> # File "<Script Block >", line 2, in <module> >>>>>> # obj.ActivePrimitive.Geometry.GetClosestLocations([0, 0, 0]) >>>>>> # File "<COMObject <unknown>>", line 2, in GetClosestLocations >>>>>> # COM Error: Invalid argument specified. - [line 2] >>>>>> >>>>>> >>>>>> On Tue, May 1, 2012 at 2:58 PM, Bradley Gabe <witha...@gmail.com>wrote: >>>>>> >>>>>>> I was going by the following quote from the docs: >>>>>>> >>>>>>> Note: Point locators are currently only supported by >>>>>>>> NurbsSurfaceMesh and PolygonMesh objects. >>>>>>> >>>>>>> >>>>>>> But I'll still give it a shot... >>>>>>> >>>>>>> >>>>>>> On Tue, May 1, 2012 at 2:54 PM, Stephen Blair < >>>>>>> stephen.bl...@autodesk.com> wrote: >>>>>>> >>>>>>>> But doesn't a PointCloudGeometry support GetClosestLocations? Can >>>>>>>> you use that (I didn't try it yet) ? >>>>>>>> >>>>>>>> >>>>>> >>>>> >>>> >>> >> >
<<338.gif>>
<<347.gif>>