Notifications
Clear all

[Closed] Place Object Offset

How do I loop through a spline and for each knot place an object 20 units from each knot as if the object was being offset. Similar to the ‘outline’ operation used for spline shapes.

http://forums.cgsociety.org/attachment.php?attachmentid=173143&stc=1


delete objects
clearlistener()

sp = splineshape wirecolor:yellow render_displayRenderMesh:false
addnewSpline sp
addKnot sp 1  #corner #line [-50,50,0]
addKnot sp 1  #corner #line [30,30,0]
addKnot sp 1  #corner #line [50,-50,0]
addKnot sp 1  #corner #line [-70,-30,0]
updateShape sp


5 Replies

It depends, the outline can get wonky if the spline is not planar really quickly. For a simple case like this for all the knots apart from the first and last vert of an open spline you can simply get an average of the vectors:

delete objects
clearlistener()

sp = splineshape wirecolor:yellow render_displayRenderMesh:false
addnewSpline sp
addKnot sp 1  #corner #line [-50,50,0]
addKnot sp 1  #corner #line [30,30,0]
addKnot sp 1  #corner #line [50,-50,0]
addKnot sp 1  #corner #line [-70,-30,0]
updateShape sp

fn getKnotPerpVec obj sp knot =
	if knot != 1 AND knot < numKnots obj 1 do
		normalize (2 * getKnotPoint obj sp knot - getKnotPoint obj sp (knot-1) - getKnotPoint obj sp (knot+1))

fn getOutlinePos obj sp knot dist =
	getKnotPoint obj sp knot + dist * getKnotPerpVec obj sp knot

Point pos:(getOutlinePos sp 1 2 20)
Point pos:(getOutlinePos sp 1 3 20)

For the first/last vert you can use a vector perpendicular to the 1st-2nd knot vector in the same plane as 1st-2nd + 2nd-3rd knot vectors or even use the node transform (again, it depends on the properties of the spline, is there anything that’s guaranteed to hold?).

As Swordslayer said but I think you need to normalize the vectors before you find their average:

clearlistener()

sp = splineshape wirecolor:yellow render_displayRenderMesh:false
addnewSpline sp
addKnot sp 1  #corner #line [-50,50,0]
addKnot sp 1  #corner #line [30,30,0]
addKnot sp 1  #corner #line [50,-50,0]
addKnot sp 1  #corner #line [-70,-30,0]
updateShape sp

fn getKnotPerpVec obj sp knot =
(
	if knot != 1 AND knot < numKnots obj 1 do
	(
		0 - normalize (normalize (getKnotPoint obj sp (knot+1) - getKnotPoint obj sp knot) + normalize (getKnotPoint obj sp (knot-1) - getKnotPoint obj sp knot))
	)
)

fn getOutlinePos obj sp knot dist = getKnotPoint obj sp knot + (dist * getKnotPerpVec obj sp knot)

Point pos:(getOutlinePos sp 1 2 20)
Point pos:(getOutlinePos sp 1 3 20)

In the case of what I’m after, the spline would always be flat on the grid. How would one calculate the first and last knot though?

1 Reply
(@alexanderh)
Joined: 11 months ago

Posts: 0

In the case of point 1, calculate the vector to point 2.
Offset based on the vector and your knot?

Same for the last point.
Get the vector of last and last-1, offset and place.

I’d suggest you do everything the way Raytracer05 does. Getting vectors perpendicular to the first and last segment in one plane then is easy enough, swap the two coordinates of axes defining the plane and negate one of them – for example in XY plane the perpedicular vectors for [0.32,0.95,0] are [-0.95,0.32,0] and [0.95,-0.32,0]. Then pick one of them for which dot product of itself and (offset vector for the neighbor knot) is positive (meaning their angle is less than 90 degrees, they point in similar direction).