This will hopefully better explain what I’m talking about.
Conditions:
- The distance between to two point3 values has to be within the limits of the max/min values
- The two point3 values can not be the same
- Stop the while/do if it has tested all the point three values in the supplied array.
How it runs:
You would supply the function an array of just point3 values as well as which index in the array is being used as the first point.
arr = #([X,X,X],[X,X,X],[X,X,X],[X,X,X],[X,X,X][X,X,X],[X,X,X])
idx = 2
The function which would return a point 3 value based on the desired conditions.
on button pressed do …
secondPt = function arr idx
second Pt would be a point3.
I’m just not entirely sure how to write up the while loop with all the conditions.
–concept code
fn fnRandomLimited arr usedIdx =
(
maxTests = arr.count
tries= 1
while newPt == usedIdx AND distance newPt usedIdx <= distMinimum OR distance newPt usedIdx >= distMaximum OR tries == maxTests do
(
newPt = arr[random 1 maxTests]
tries+= 1
)
return newPt
)
It doesn’t seem like it would be to intense of a calculation but maybe I am wrong about that.
I’m messing around with trying to come up with different solutions to see what works and what doesn’t.
I added only the snippet of code at the bottom to create the lines.
Right now when I run it it creates hundreds of lines which are all the same.
What I was hoping it would do is …
cycle through each item in positions and try to create a spline shape, making the second knot’s position a random point3 found in the positions array, as long as its not the same position as the starting knot AND within the distance constraints.
(
delete objects
sp = geosphere name:"points" radius:40 segments:2
mesh = snapshotasmesh sp
points = mesh.verts as bitarray
positions = for p in points collect (getvert mesh p)
connections = #()
dmax = 60
dmin = 10
fn getDistance base p = distance positions[base] positions[p]
fn makeConnect base p = append connections [base, p]
while not points.isempty do
(
base = undefined
for p in (copy points) do
(
if base == undefined then
(
deleteitem points p
base = p
)
else
(
d = getDistance base p
if not (d > dmax or d < dmin) do
(
makeConnect base p
deleteitem points p
)
)
)
)
connections
)
for p = 1 to connections.count do
(
pt1 = connections[1][1]
pt2 = connections[1][2]
s = splineShape()
idx = addnewSpline s
addKnot s idx #smooth #curve positions[pt1]
addKnot s idx #smooth #curve positions[pt2]
updateShape s
select s
)
that means you want to have smooth distribution of base connectors, right?
you can limit number of connections to one point… also you can shuffle the list of points. (there is a thread about it… some mini-challenge… #1 or #2)
I think i’ve got it.
This seems to be doing exactly what I want. I’ve simplified it down to the bare bones of just single numbers. It was easier to wrap my head around.
Let me know what you think.
The dmin and dmax will just get replaced with distance calculations between the point3 values.
range = #(1,2,3,4,5,6,7,8,9,10)
fn fnUniqueRandom arr used =
(
dMax = 8
dMin = 4
newNum = used
while newNum == used OR newNum > dMax OR newNum < dMin do
(
newNum = ceil (random (arr[1]) (arr[arr.count]))
)
return newNum
)
clearlistener()
fnUniqueRandom range 6
Practically you back to the beginning with a small additions (dmin and [b]dmax).
Great!
[/b]
OK so now going forth with that and implementing the point3 values it gets choked up when i change the min and max values?
I dont get it?
Ideally it would be nice to be able to lower the max value to 20 or so which would result and not many strands being strung across long distances.
Same goes for the min value, it would be raised to exclude short strands from being created.
Try this out and let me know if you can get it working with different min max values…
(
delete objects
obj = Torus_Knot smooth:2 Base_Curve:0 Segments:20 sides:3 radius:19.9803 radius2:6.10344 p:2 q:3 Eccentricity:1 Twist:0 Lumps:0 Lump_Height:0 Gen_UV:1 U_Tile:1 V_Tile:1 u_offset:0 v_offset:0 Warp_Height:0 Warp_Count:0 pos:[0,0,0] isSelected:off
mesh = snapshotasmesh obj
points = mesh.verts as bitarray
range = for p in points collect (getvert mesh p)
--delete obj
fn fnUniqueRandom arr used =
(
dMax = 100
dMin = 5
newNum = used
attempts = 1
while attempts > arr.count OR newNum == used OR distance newNum used > dMax OR distance newNum used < dMin do
(
newNum = (random (arr[1]) (arr[arr.count]))
attempts += 1
)
return newNum
)
s = splineShape()
for i = 1 to range.count do
(
pt1 = range[i]
pt2 = fnUniqueRandom range range[i]
idx = addnewSpline s
addKnot s idx #smooth #curve pt1
addKnot s idx #smooth #curve pt2
)
updateShape s
select s
)
Alright so a much simpler and quicker solution is doing a deleteSpline function after each line as been created if it is to long so I’m going to do something like this.
I will have to figure out a way to implement this where it works. Right now it will break because once it deletes one spline the number of splines in the arr is no longer valid.
dMin = 100
dMax = 200
theShape = $
for idx = 1 to numSplines theShape do
(
pathLength = curveLength theShape idx
if pathLength <= dMin OR pathLength >= dMax do
(
deleteSpline theShape idx
)
)
do the same but in backward order:
for idx = (numSplines theShape) to 1 by -1 do ...
but it’s not the right way. it’s much faster to do the distance check before creation then delete splines after…