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 NurbsSurfaceMeshand
>>>>>> 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) ?
>>>>>>
>>>>>>
>>>>
>>>
>>
>

<<347.gif>>

Reply via email to