Open summer-tree opened 4 years ago
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.
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())
}
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.
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?
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.
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.
Hello. Is there any way to extrude shape along curve?