PDA

View Full Version : Knot re-ordering problem

 Archtic02-13-2008, 12:45 AMHi Everybody, I've been trying to come up with a script that takes an input spline, and rearranges the knots according to their distance from each other, with the first knot being fixed, then the next nearest knot, then the next nearest to that, etc....... So far I've come up with this: ( originalpointarray = for i = 1 to (numknots \$ 1) collect (getknotpoint \$ 1 i) pointarray = originalpointarray newpoints = #() newpoint = [0,0,0] indexcheck = 0 for i = 1 to originalpointarray.count do ( checkdist = 9999.0 --if pointarray.count == 1 do continue for j = 1 to pointarray.count do ( if pointarray[i] == pointarray[j] do continue newdist = distance pointarray[i] pointarray[j] if newdist <= checkdist then ( checkdist = newdist newpoint = pointarray[j] indexcheck = j ) ) append newpoints newpoint deleteitem pointarray indexcheck ) print newpoints ) This takes a selected spline, and tests each point against an array of the same points, identifying the closest one, then deleting that value from the array that contains the remaining points to be checked against. It finally outputs the new ordered array of knots... But still no joy.... I have a feeling I'm missing something! Any pointers would be greatly appreciated. Archtic.
Kramsurfer
02-13-2008, 05:44 PM
Here's a revision that's a bit different.. I build an "ToPoint" index array that lets you know to which point is the shortest from the current point. I also use a bitarray #{} as a flagging system to see if the point has been used or not.

I'm then constructing a new spline from the data.

(
originalpointarray = for i = 1 to (numknots \$ 1) collect (getknotpoint \$ 1 i)
ToPointArray = #( 1 )
PointUsed = #{ 1 }

for i = 2 to originalpointarray.count do
(
local checkdist = 999999.0
local ShortestPoint = 0
local newdist
for j = 1 to originalpointarray.count do
(
if (( i != j ) and ( not PointUsed[ j ] )) then
(
newdist = distance originalpointarray[ToPointArray[ToPointArray.count]] originalpointarray[j]
if (newdist <= checkdist) then
(
checkdist = newdist
ShortestPoint = j
)
)
)
PointUsed[ ShortestPoint ] = true
append ToPointArray ShortestPoint
)
tnShape = SplineShape()
for i = 1 to ToPointArray.count do
(
addKnot tnShape 1 #corner #line originalpointarray[ ToPointArray[i] ]
)
)

Looking at yours again... don't you want to compare the distance from the orginial array and the remaining ones? Also when you set an Array value to a variable in MaxScript, you get a reference to the array, not a unique value. So you are effectively deleteing Items from a single array in memory

Listener
Array1= #(4,5,6)
#(4, 5, 6)
Array2 = Array1
#(4, 5, 6)
Array1[2]=10
10
Array2
#(4, 10, 6)

Archtic
02-13-2008, 10:17 PM
Thanks Kramsurfer, appreciate your help on this. The flagging system is a useful little routine, and yes, I forgot about array reference.... which would explain some of the problems!

I've just been runing your script on a few examples, and have got some weired behaviour... for instance:

setting originalpointarray as #([1714.34,-1424.13,0], [2827.51,-875.123,0], [2102.58,-1236.07,0], [3236.99,-671.901,0])

gives a runtime error that shortestpoint is 0..... so i'll try and tease that one out...

and setting originalpointarray as #([898.417,-1642.51,0], [2691.02,-699.199,0], [1432.25,-1345.26,0], [2939.74,-565.74,0], [3327.98,-362.518,0])

produces the new line: #([898.417,-1642.51,0], [1432.25,-1345.26,0], [2691.02,-699.199,0], [3327.98,-362.518,0], [2939.74,-565.74,0])

which has the correct order of the last two points transposed...... odd..

I'll post some code when I've had time to work on it. Thanks again.

Archtic
02-14-2008, 05:06 PM
Ok, think I've fixed it:

(
originalpointarray = for i = 1 to (numknots \$ 1) collect (getknotpoint \$ 1 i)
ToPointArray = #(1)
PointUsed = #{ 1 }

for i = 2 to originalpointarray.count do
(
local checkdist = 999999.0
local ShortestPoint = 0
local newdist
for j = 1 to originalpointarray.count do
(
if ((originalpointarray[topointarray[topointarray.count]] != originalpointarray[j]) and ( not pointused[j])) then --(( i != j ) and ( not PointUsed[ j ] )) then
(
newdist = distance originalpointarray[topointarray[topointarray.count]] originalpointarray[j]
if (newdist <= checkdist) then
(
checkdist = newdist
ShortestPoint = j
)
)
)
PointUsed[ ShortestPoint ] = true
append ToPointArray ShortestPoint
)
tnShape = SplineShape()
for i = 1 to ToPointArray.count do
(
addKnot tnShape 1 #corner #line originalpointarray[ ToPointArray[i] ]
)
)

I changed the test i != j to do a comparison between the point3 values instead.. this seems to have worked out the kinks...

Thanks again.

A.

Kramsurfer
02-14-2008, 05:45 PM
ahhh. yeah the current point makes more sense.... good job... I'll update this in my Snibbit library... thanks..

CGTalk Moderation
02-14-2008, 05:45 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.