Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extrude along curve #17

Open
summer-tree opened this issue Sep 8, 2020 · 6 comments
Open

extrude along curve #17

summer-tree opened this issue Sep 8, 2020 · 6 comments

Comments

@summer-tree
Copy link

Hello. Is there any way to extrude shape along curve?

@deadsy
Copy link
Owner

deadsy commented Sep 8, 2020

It's not currently supported.
In general you'd need to define the curve, a normal to the curve, and the 2d shape you want to extrude.
Then the tricky part is working out the SDF for such a thing- suffice to say that you can't just map the 3d coordinate back to the plane of the 2d shape- it's tricky, you'd probably need some sort of iterative method.

@soypat
Copy link
Contributor

soypat commented Jan 17, 2022

Well I gave it a shot and fell flat on my face when I had to take the orthogonal projection of a vector over a plane. I have it more or less thought out but I can't find an algorithm for doing said operation so I'll leave my code here if someone wants to pick it up immediately. I think I might give it a shot again sometime in the future

// Patricio Whittingslow Copyleft 2022
// LICENSE: WTFPL

package sdf_test

import (
	"testing"

	"github.com/deadsy/sdfx/render"
	"github.com/deadsy/sdfx/sdf"
)

type CurveExtrude struct {
	// Parametrized curve
	f  func(t float64) sdf.V3
	g  func(t float64) sdf.SDF2
	dt float64
}

const (
	L = 10
	H = 3
	W = 4
)

func TestArb(t *testing.T) {
	shape := sdf.Box2D(sdf.V2{H, W}, H/10)
	a := CurveExtrude{
		f: func(t float64) sdf.V3 {
			return sdf.V3{t * L, 0, 0}
		},
		g: func(t float64) sdf.SDF2 {
			return shape
		},
		dt: L / 20,
	}
	render.RenderSTLSlow(a, 100, "extrude")
}

func (a CurveExtrude) BoundingBox() sdf.Box3 {
	return sdf.NewBox3(sdf.V3{L / 2, 0, 0}, sdf.V3{L, 0, 0})
}

func (a CurveExtrude) Evaluate(p sdf.V3) float64 {
	dt2 := a.dt / 2
	for t := a.dt; t <= 1; t += a.dt {
		// We define the plane where the SDF2 lives with center (point) and n (vector).
		center := a.f(t) // Center point of evaluation.
		// Acquire the 3D direction of the curve. The normal vector.
		n := a.f(t + dt2)
		n = n.Sub(a.f(t - dt2))
		// We obtain the projection of p onto the plane. this will let us know how to transform p.
		pv := p.Sub(center) // vector to point.

	}
	return 1 //TODO
}

func v3cos(a, b sdf.V3) float64 {
	return a.Dot(b) / (a.Length() * b.Length())
}

@deadsy
Copy link
Owner

deadsy commented Jan 18, 2022

The loop in the evaluate function is going to kill performance - that's why I suggested an iterative solution. In many cases the solution for a new point is likely close to the solution for neighboring points. If you already have an ok solution - an iteration or two may make it a very good solution.

@soypat
Copy link
Contributor

soypat commented Jan 18, 2022

So there's a pattern to the points received by Evaluate method? Sequential calls of Evaluate will have points that tend to be near to eachother?

@deadsy
Copy link
Owner

deadsy commented Jan 18, 2022

Sequential calls of Evaluate will have points that tend to be near to each other

Well - yes (as a practical matter) but in general no. ie - the calls to evaluate are independent and some renderers will have calls all over the place. Still - if you can do some form of solution caching it may pay-off. Finding a cache entry that is "close" to an existing entry is an interesting problem.

@deadsy
Copy link
Owner

deadsy commented Jan 18, 2022

btw - this method is not unlike that for working out screw threads where the evaluation point is projected onto the 2d thread form. The screw thread evaluation is slightly incorrect (it doesn't work properly with the octree based renderer) and I think this more general method is also going to be wrong- although probably still useful with the uniform cube renderer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants