1 package shape
2
3 import (
4 "math"
5
6 "oss.terrastruct.com/d2/lib/geo"
7 "oss.terrastruct.com/d2/lib/svg"
8 "oss.terrastruct.com/util-go/go2"
9 )
10
11 type shapePerson struct {
12 *baseShape
13 }
14
15 func NewPerson(box *geo.Box) Shape {
16 shape := shapePerson{
17 baseShape: &baseShape{
18 Type: PERSON_TYPE,
19 Box: box,
20 },
21 }
22 shape.FullShape = go2.Pointer(Shape(shape))
23 return shape
24 }
25
26 const (
27 PERSON_AR_LIMIT = 1.5
28
29 personShoulderWidthFactor = 20.2 / 68.3
30 )
31
32 func (s shapePerson) GetInnerBox() *geo.Box {
33 width := s.Box.Width
34 tl := s.Box.TopLeft.Copy()
35 shoulderWidth := personShoulderWidthFactor * width
36 tl.X += shoulderWidth
37 width -= shoulderWidth * 2
38 return geo.NewBox(tl, width, s.Box.Height)
39 }
40
41 func personPath(box *geo.Box) *svg.SvgPathContext {
42 pc := svg.NewSVGPathContext(box.TopLeft, box.Width/68.3, box.Height/77.4)
43
44
45 pc.StartAt(pc.Absolute(68.3, 77.4))
46 pc.H(false, 0)
47 pc.V(true, -1.1)
48 pc.C(true, 0, -13.2, 7.5, -25.1, 19.3, -30.8)
49 pc.C(false, 12.8, 40.9, 8.9, 33.4, 8.9, 25.2)
50 pc.C(false, 8.9, 11.3, 20.2, 0, 34.1, 0)
51
52
53
54
55 pc.C(true, 13.9, 0, 25.2, 11.3, 25.2, 25.2)
56
57 pc.C(true, 0, 8.2, -3.8, 15.6, -10.4, 20.4)
58 pc.C(true, 11.8, 5.7, 19.3, 17.6, 19.3, 30.8)
59 pc.V(true, 1)
60 pc.H(false, 68.3)
61 pc.Z()
62 return pc
63 }
64
65 func (s shapePerson) Perimeter() []geo.Intersectable {
66 return personPath(s.Box).Path
67
68 }
69
70 func (s shapePerson) GetSVGPathData() []string {
71 return []string{
72 personPath(s.Box).PathData(),
73 }
74 }
75
76 func (s shapePerson) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) {
77 totalWidth := width + paddingX
78
79 shoulderWidth := totalWidth * personShoulderWidthFactor / (1 - 2*personShoulderWidthFactor)
80 totalWidth += 2 * shoulderWidth
81 totalHeight := height + paddingY
82
83
84 totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, PERSON_AR_LIMIT)
85 return math.Ceil(totalWidth), math.Ceil(totalHeight)
86 }
87
88 func (s shapePerson) GetDefaultPadding() (paddingX, paddingY float64) {
89 return 10, defaultPadding
90 }
91
View as plain text