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 <[email protected]>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 <[email protected]> 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 <[email protected]>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 <[email protected]> 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 <[email protected]>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 <[email protected]>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 <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> But doesn't a PointCloudGeometry support GetClosestLocations? Can
>>>>>>> you use that (I didn't try it yet) ?
>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>
>>
>
<<338.gif>>
<<347.gif>>

