Notifications
Clear all

[Closed] Filtering Points

Does anyone know of a good way for me to loop through all the selected points, in the order they are selected, and remove any points that would create a middle point on a straight line.

The image below should help explain. The test script below creates the points seen in the image. What I want in return is an array of the points which are highlighted ‘green’, avoiding any points that would create a straight. Hopefully this makes sense. Thanks guys.


pts = #( [0,0,0] , [0,2,0] , [0,4,0] , [0,6,0] , [0,8,8] , [0,10,10] , [0,12,12] , [0,16,12])

for p in pts do
 	point pos:p size:1 wirecolor:red

11 Replies
 lo1

assuming points A, B, C where B is between A and C


fn IsRedundant A B C thresh:0.001 =
(
  local v1 = B - A
  local v2 = C - A
  local d = dot (normalize v1) (normalize v2)
  return (length v2 > length v1) and abs(1.0 - d) < thresh
)

Thats great Rotem. thank you.

What do you think is the best way to go about checking an array of items and returning the ‘clean array’?

A while loop of some sort?


pts = #( [0,0,0] , [0,2,0] , [0,4,0] , [0,6,0] , [0,8,8] , [0,10,10] , [0,12,12] , [0,16,12])

for p in pts do
 	point pos:p size:1 wirecolor:red
	
fn IsRedundant A B C thresh:0.001 =
(
	local v1 = B - A
	local v2 = C - A
	local d = dot (normalize v1) (normalize v2)
	
	return (length v2 > length v1) and abs(1.0 - d) < thresh
)

IsRedundant pts[5] pts[6] pts[7]
 lo1

Well, the first and last points are obviously not redundant.

You can add the first point to an empty array, loop N-2 timers starting with {1,2,3} up until {n-2,n-1,n }, appending only the non-redundant points, and then adding the last point.

I’m thinking more like this though, say I append one of the points to the array which then creates a straight point, i need to recursively filter the pts until they all test false.

Explained more:…
here is my starting array (the first and last point)

1—–2——3——–4
If i test 1,2,3 it tests ‘true’ for redudance. I would then get this in return

1—–3——–4
Now i would need to test 1,3,4

And then get this in return
1,4

So wouldn’t i need to continue testing until i get false for redundance, then continue to the next set of points.

 lo1

yeah fair point, do it like that.

That’s where i’m having a tough time wrapping my head around a way to write this recursively testing function, at the end resulting in a clean array of filtered points.

 lo1
fn filterRedundantPoints pArr =
(
	local filtered = copy pArr #nomap
	local p = 1
	while (p < filtered.count - 2) do
	(
		local a = filtered[p]
		local b = filtered[p + 1]
		local c = filtered[p + 2]
		if IsRedundant a b c then
		(
			deleteItem filtered (p + 1)
		)
		else
		(
			p+=1
		)
	)
	filtered
)

It’s not recursive, just iterative.

awwwww sheeet… Nice Rotem.
I was unable to wrap my head around this one as I’m very appreciative of your help. After seeing your logic and layout, it makes sense, but it’s not something I would have been able to come up with as cleanly and as quickly as you did.

 lo1

this is a more efficient redundancy check:

fn IsRedundant A B C thresh:0.001 =
(
	local v1 = A - B
	local v2 = C - B
	local d = dot (normalize v1) (normalize v2)
	return abs(d + 1) < thresh
)
Page 1 / 2