-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompound_test.go
More file actions
95 lines (82 loc) · 3.02 KB
/
Copy pathcompound_test.go
File metadata and controls
95 lines (82 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package sketch_test
import (
"encoding/json"
"math"
"testing"
"github.com/lestrrat-3d/sketch"
"github.com/stretchr/testify/require"
)
func TestCreateRectangle(t *testing.T) {
s := newSketch(t)
r := s.CreateRectangle(0, 0, 18, 2) // rough initial size
s.Fix(r.A)
s.AddConstraint(sketch.NewDistance(r.A, r.B, 20))
s.AddConstraint(sketch.NewDistance(r.A, r.D, 12))
res, err := s.Solve(t.Context())
require.NoError(t, err)
require.Equal(t, 0, res.DOF, "fully constrained")
require.InDelta(t, 20, r.C.X(), 1e-6, "c.X")
require.InDelta(t, 12, r.C.Y(), 1e-6, "c.Y")
require.InDelta(t, 0, r.D.X(), 1e-6, "d.X")
require.InDelta(t, 12, r.D.Y(), 1e-6, "d.Y")
}
func TestCreatePolygon(t *testing.T) {
s := newSketch(t)
p, err := s.CreatePolygon(0, 0, 6, 5)
require.NoError(t, err)
s.Fix(p.Center)
s.Fix(p.Vertices[0]) // at (5, 0): pins rotation and size
// Knock a far vertex off the circle so the solve does real work.
p.Vertices[3].MoveTo(-4.5, 0.8)
res, err := s.Solve(t.Context())
require.NoError(t, err)
require.Equal(t, 0, res.DOF, "fully constrained")
for i, v := range p.Vertices {
require.InDeltaf(t, 5, math.Hypot(p.Center.X()-v.X(), p.Center.Y()-v.Y()), 1e-6, "vertex %d circumradius", i)
}
for i, side := range p.Sides {
require.InDeltaf(t, 5, side.Length(), 1e-6, "side %d (hexagon side == r)", i)
}
}
func TestCreatePolygonInvalid(t *testing.T) {
s := newSketch(t)
_, err := s.CreatePolygon(0, 0, 2, 5)
require.ErrorIs(t, err, sketch.ErrInvalidShape, "n < 3")
}
func TestCreateSlot(t *testing.T) {
s := newSketch(t)
sl, err := s.CreateSlot(0, 0, 10, 0, 2) // built at radius 2, driven to 3 below
require.NoError(t, err)
s.Fix(sl.C1)
s.Fix(sl.C2)
require.Equal(t, 1, s.DOF(), "only the radius is free (contact points pinned)")
s.AddConstraint(sketch.NewDistance(sl.L1.Start, sl.C1, 3)) // cap contact point to center == radius
res, err := s.Solve(t.Context())
require.NoError(t, err)
require.Equal(t, 0, res.DOF, "fully constrained")
require.InDelta(t, 3, sl.A1.R(), 1e-6, "cap 1 radius")
require.InDelta(t, 3, sl.A2.R(), 1e-6, "cap 2 radius (equal)")
require.InDelta(t, -3, sl.L1.Start.Y(), 1e-6, "right flank start")
require.InDelta(t, -3, sl.L1.End.Y(), 1e-6, "right flank end")
require.InDelta(t, 3, sl.L2.Start.Y(), 1e-6, "left flank start")
require.InDelta(t, 3, sl.L2.End.Y(), 1e-6, "left flank end")
}
func TestJSONRoundTripSlot(t *testing.T) {
s := newSketch(t)
sl, err := s.CreateSlot(0, 0, 10, 0, 3)
require.NoError(t, err)
s.Fix(sl.C1)
s.Fix(sl.C2)
s.AddConstraint(sketch.NewDistance(sl.L1.Start, sl.C1, 3))
_, err = s.Solve(t.Context())
require.NoError(t, err)
data, err := json.Marshal(s)
require.NoError(t, err, "marshal")
var s2 sketch.Sketch
require.NoError(t, json.Unmarshal(data, &s2), "unmarshal")
require.Len(t, s2.Entities(), len(s.Entities()), "entities survive")
require.Len(t, s2.Constraints(), len(s.Constraints()), "constraints survive (internal ones recreated, not doubled)")
res, err := s2.Solve(t.Context())
require.NoError(t, err)
require.Equal(t, 0, res.DOF, "reloaded DOF")
}