"""
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>>

Reply via email to