Notifications
Clear all

[Closed] inverted archs

So I’m working on generating positions in this circular fashion and I’ve the outer circle and linear parts working. I’m not sure how to get the inverted archs to work appropriately. I was hoping to get some help on that. If you look at the picture I got the green and yellow parts working but not sure how to calculate the red? Script is below.

Feel free to play around and change up the columns variable to any number higher than 3.


steps = 6
height = 0.0
width = 30.0
len = 30
radiusX = 15
radiusY = 15
fourCorners = #()
rounded = .5

delete objects
/* Create Circle */
columns = 4 --don't got lower than 3
columnAngle = 360.0 / columns
subCounter = 0

clearlistener()
/* Create Corner Points */
for c = 1 to columns do
(									
	calcX = radiusX * cos((c-1) * columnAngle)
	calcY = radiusY * sin((c-1) * columnAngle)
	
	cornerPos = [calcX,calcY,height]
	point pos:cornerPos size:4 wirecolor:blue
	append fourCorners cornerPos
	subCounter += 1
	
 	/* Create Sub Points */
	subColumns = (steps*columns+columns)
	subAngle = 360.0 / subColumns
	for s = 1 to steps do
	(
		/* Circular Calculations */
		subCounter += 1
 		calcXRadial = radiusX * cos((subCounter-1) * subAngle)
  		calcYRadial = radiusY * sin((subCounter-1) * subAngle)
		circularPos = [calcXRadial,calcYRadial,height]
		point pos:circularPos size:2 wirecolor:green
		
 		/* Linear Calculations */
		calcXLinear = radiusX * cos((c) * columnAngle)
 		calcYLinear = radiusY * sin((c) * columnAngle)
		nextCorner = [calcXLinear,calcYLinear,height]
		linearPos = (cornerPos + ((nextCorner-cornerPos)*(((s as float)/(steps+1)))))
		point pos:linearPos size:2 wirecolor:yellow
  		append fourCorners circularPos
			
		/* Inverted Circular Calculations */	
	)	
)

12 Replies

Hi John,

Since you already have the position on the outer circle circularPos and the line linearPos, you should be able to simply use:

circularInvPos = linearPos - (circularPos - linearPos)

to get the position on the other side of the line.

Cheers,
Martijn

Never mind my previous post, that will obviously not return the correct position. Next time I should actually test it in max before posting

Maybe this

Hey Martjin I ended up getting it to work I did this.

linearPos + (linearPos + circularPos)

Now how would I go about doing this.
I’m trying to randomly rotate the position of each arc 90 degrees from the previous arch. Trying to make it look like something similar to the image below.


(
	clearlistener()
	delete objects
	local radiusA = 10.0
	local steps = 4
	local knotsPerArch = 6
	local rotAngle = 180.0 / knotsPerArch
	local startPos = [0,0,0]
	local sp = splineShape wirecolor:yellow
	local posArr = #() 
	
	addnewSpline sp
	addKnot sp 1 #corner #curve sp.pos --first knot created at origin

	for s = 1 to steps do
	(
		format "Arch: %
" s
		for k = 2 to knotsPerArch+1 do --skip first knot which is always created at origin
		(							
			calcX = radiusA * cos((k-1) * rotAngle)
			calcY = radiusA * sin((k-1)* rotAngle)
			
			pos = [0,calcX,calcY] + startPos --include nodes matrix
			append posArr pos
 			point pos:pos size:2 wirecolor:(red/(s as float))
		)
		startPos += [0,(radiusA*2),0]
	)
)

closer but not quite…


(
	clearlistener()
	delete objects
	local radiusA = 10.0
	local steps = 4
	local knotsPerArch = 6
	local rotAngle = 180.0 / knotsPerArch
	local startPos = [0,0,0]
	local sp = splineShape wirecolor:yellow
	local posArr = #() 
	
	fn shuffleIndexes count = --unique Random order
	(
		list = #() 	
		list.count = count
		for k = 1 to count do 
		(
			i = random 1 k
			list[k] = list[i]
			list[i] = k
		)
		return list
	)

	addnewSpline sp
	addKnot sp 1 #corner #curve sp.pos --first knot created at origin

	for s = 1 to steps do
	(
		format "Arch: %
" s
		ids = shuffleIndexes 3
		for k = 2 to knotsPerArch+1 do --skip first knot which is always created at origin
		(							
			calcX = radiusA * cos((k-1) * rotAngle)
			calcY = radiusA * sin((k-1)* rotAngle)
			
			pos = [0,calcX,calcY] + startPos --include nodes matrix
			
			newPos = [pos[ids[1]],pos[ids[2]],pos[ids[3]]]
			
			append posArr pos
 			point pos:newPos size:2 wirecolor:(red/(s as float))
		)
		startPos += [0,(radiusA*2),0]
	)
)

Hey John,

Had some time to look at this again, and as I said the method I posted earlier is wrong, here is one of the possible ways to do it:

/* Inverted Circular Calculations */
d1 = circularPos - cornerPos
v1 = normalize d1
v2 = normalize (linearPos - cornerPos)
v3 = 2 * (dot v1 v2) * v2 - v1
circularInvPos = cornerPos + (v3 * (length d1))
point pos:circularInvPos size:2 wirecolor:red

Martijn

getting closer.


(
	delete objects
	local columns = 9
	local columnAngle = 180.0 / (columns-1)
	local steps = 6
	local origin = [0,0,0]
	local allArchs = #()
	
	/*Set Vertices*/
	for s = 1 to steps do
	(
		local radius = random 5.0 10.0
		local col = random [150,150,150] [255,255,255]
		local archArr = #()
		
		for v = 1 to columns do
		(									
			calcX = radius * cos((v-1) * columnAngle)
			calcY = radius * sin((v-1)* columnAngle)
			
			pos = [0,calcX,calcY]--include nodes matrix
			
			if v == 1 do origin = [0,0,0] - pos
				
			setPos = pos + origin
			
			p = point pos:setPos size:2 wirecolor:col
			append archArr p
		)
		append allArchs archArr
	)
	
	/*Offset Vertices*/
	clearlistener()
	for a=2 to allArchs.count do
	(
		preArcSet = allArchs[a-1]
		arcSet = allArchs[a]
		calcOffset = arcSet[1].pos - preArcSet[columns].pos
		
		for p in arcSet do
		(
			p.pos -= calcOffset
		)
	)
)

Maybe this


(
	delete objects
	local columns = 9
	local columnAngle = 180.0 / (columns-1)
	local steps = 5
	local origin = [0,0,0]
	local allArchs = #()

	/*Set Vertices*/
	for s = 1 to steps do
	(
		local radius = random 5.0 10.0
		local col = random [150,150,150] [255,255,255]
		local archArr = #()
		
		for v = 1 to columns do
		(	
			num = v-1	
			calcX = radius * cos((num) * columnAngle)
			calcY = radius * sin((num)* columnAngle)
			
			pos = [calcX,calcY,0]--include nodes matrix
			if v == 1 do origin -= pos
			setPos = pos + origin
			case of (
				(s == 1 and v == 1): archArr[v] = point pos:setPos size:2 wirecolor:col
				(s > 1 and v == 1): in ((allArchs[s-1])[allArchs[s-1].count]) (archArr[v] = point pos:setPos size:2 wirecolor:col)
				default: in archArr[v-1] (archArr[v] = point pos:setPos size:2 wirecolor:col)
			)
		)
		origin = archArr[columns].pos
		append allArchs archArr
	)
	angArr = #((EulerAngles 0 90 0),(EulerAngles 0 -90 0),(EulerAngles 90 0 0),(EulerAngles -90 0 0))
	for m = 2 to allArchs.count do (in coordsys parent rotate allArchs[m][1] angArr[random 1 4])
)

Example with arc shapes

(
	delete objects
	local splKnots = 5, kAngle = 180.0 / (splKnots-1), num = 10, origin = [0,0,0], allArchs = #()
	for s = 1 to num do
	(
		radius = random 5.0 10.0
		spl = splineShape name:(uniqueName "ArcShape") wirecolor:(random [50,50,50] [255,255,255]) pos:origin isSelected:off
		addNewSpline spl		
		for v = 1 to splKnots do
		(	
			calcX = radius * cos((v-1) * kAngle)
			calcY = radius * sin((v-1)* kAngle)
			pos = [calcX,calcY,0]
			if v == 1 do origin -= pos
			addKnot spl 1 #smooth #curve (pos + origin)
		)
		updateShape spl
		origin = getKnotPoint spl 1 (numKnots spl)
		if (cnt = allArchs.count) != 0 do spl.parent = allArchs[cnt]
		append allArchs spl
	)
	angArr = #((EulerAngles 0 90 0),(EulerAngles 0 -90 0),(EulerAngles 90 0 0),(EulerAngles -90 0 0))
	for m = 2 to allArchs.count do (in coordsys parent rotate allArchs[m] angArr[random 1 4])
)
Page 1 / 2