|
- package objects
-
- import (
- "github.com/deadsy/sdfx/sdf"
- "math"
- )
-
- type BoxParams struct {
- Size sdf.V3 // internal box size
- Wall float64 // wall thickness
- BottomTopRatio float64 // ratio between the height of the top and the bottom
- CornerRadius float64 // radius of rounded corners
- Taper float64 // angle of split
- ClosingHeight float64 // height of the closing
- Margin float64 // Margin for closing
- Text string
- }
-
- func Box3D(k *BoxParams) (top sdf.SDF3, bottom sdf.SDF3, err error) {
- top, err = TopBox3D(k)
- bottom, err = TopBox3D(k)
- if err != nil {
- return
- }
- return
- }
-
- func baseBox3D(k *BoxParams) (sdf.SDF3, error) {
- box, err := sdf.Box3D(k.Size.AddScalar(k.Wall*2), k.CornerRadius)
- if err != nil {
- return nil, err
- }
- return box, nil
- }
-
- func TopBox3D(k *BoxParams) (top sdf.SDF3, err error) {
- box, err := baseBox3D(k)
- if err != nil {
- return
- }
- a := sdf.V3{X: 0, Y: 0, Z: 0.5 - k.BottomTopRatio}.Mul(k.Size).Add(sdf.V3{X: 0, Y: 0, Z: k.ClosingHeight / 2})
- n := sdf.V3{X: 0, Y: 0, Z: 1}
- top = sdf.Cut3D(box, a, n)
- closing, err := InnerClosing(k)
- if err != nil {
- return
- }
- top = sdf.Union3D(top,closing)
- return
- }
-
- func BottomBox3D(k *BoxParams) (bottom sdf.SDF3, err error) {
- box, err := baseBox3D(k)
- if err != nil {
- return
- }
- a := sdf.V3{X: 0, Y: 0, Z: 0.5 - k.BottomTopRatio}.Mul(k.Size).Add(sdf.V3{X: 0, Y: 0, Z: k.ClosingHeight / 2})
- n := sdf.V3{X: 0, Y: 0, Z: -1}
- bottom = sdf.Cut3D(box, a, n)
- closing, err := InnerClosing(k)
- scale := k.Size.Add(sdf.V3{X: k.Margin, Y: k.Margin, Z: 0}).Div(k.Size)
- closing = sdf.Transform3D(closing, sdf.Scale3d(scale))
- if err != nil {
- return
- }
- bottom = sdf.Difference3D(bottom,closing)
- return
- }
-
- func InnerClosing(k *BoxParams) (closing sdf.SDF3, err error) {
- offset := math.Tan(k.Taper) * k.ClosingHeight / 2
- size := sdf.V2{X: k.Size.X, Y: k.Size.Y}
- s1 := sdf.Box2D(size.AddScalar(k.Wall-offset), k.CornerRadius)
- s2 := sdf.Box2D(size.AddScalar(k.Wall+offset), k.CornerRadius)
- closing, err = sdf.Loft3D(s1, s2, k.ClosingHeight, 0)
- if err != nil {
- return
- }
- closing = sdf.Transform3D(closing, sdf.Translate3d(sdf.V3{0,0,0.5-k.BottomTopRatio}.Mul(k.Size)))
- return
- }
-
- func OuterClosing(k *BoxParams) (closing sdf.SDF3, err error) {
- s0, err := InnerClosing(k)
- if err != nil {
- return
- }
- s1, err := baseBox3D(k)
- if err != nil {
- return
- }
- a := sdf.V3{0, 0, k.ClosingHeight / 2}
- n := sdf.V3{0, 0, -1}
- s1 = sdf.Cut3D(s1, a, n)
- s1 = sdf.Cut3D(s1, a.Neg(), n.Neg())
- closing = sdf.Difference3D(s1, s0)
- return
- }
|