use per-axis padding

This commit is contained in:
Gavin Nishizawa 2023-02-10 16:19:19 -08:00
parent 93fa13ab0f
commit 94bf92a28b
No known key found for this signature in database
GPG key ID: AE3B177777CE55CD
5 changed files with 20 additions and 15 deletions

View file

@ -863,6 +863,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
} }
} }
// to examine GetInsidePlacement
// padX, padY := s.GetDefaultPadding()
// innerTL := s.GetInsidePlacement(s.GetInnerBox().Width, s.GetInnerBox().Height, padX, padY)
// fmt.Fprint(writer, renderOval(&innerTL, 5, 5, "fill:red;"))
// Closes the class=shape // Closes the class=shape
fmt.Fprint(writer, `</g>`) fmt.Fprint(writer, `</g>`)

View file

@ -47,7 +47,7 @@ type Shape interface {
GetInnerBox() *geo.Box GetInnerBox() *geo.Box
// placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft // placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft
GetInsidePlacement(width, height, padding float64) geo.Point GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point
GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64)
GetDefaultPadding() (paddingX, paddingY float64) GetDefaultPadding() (paddingX, paddingY float64)
@ -88,9 +88,9 @@ func (s baseShape) GetInnerBox() *geo.Box {
return s.Box return s.Box
} }
func (s baseShape) GetInsidePlacement(_, _, padding float64) geo.Point { func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point {
innerTL := (*s.FullShape).GetInnerBox().TopLeft innerTL := (*s.FullShape).GetInnerBox().TopLeft
return *geo.NewPoint(innerTL.X+padding/2, innerTL.Y+padding/2) return *geo.NewPoint(innerTL.X+paddingX/2, innerTL.Y+paddingY/2)
} }
// return the minimum shape dimensions needed to fit content (width x height) // return the minimum shape dimensions needed to fit content (width x height)

View file

@ -25,7 +25,7 @@ func NewCircle(box *geo.Box) Shape {
func (s shapeCircle) GetInnerBox() *geo.Box { func (s shapeCircle) GetInnerBox() *geo.Box {
width := s.Box.Width width := s.Box.Width
height := s.Box.Height height := s.Box.Height
insideTL := s.GetInsidePlacement(width, height, 0) insideTL := s.GetInsidePlacement(width, height, 0, 0)
tl := s.Box.TopLeft.Copy() tl := s.Box.TopLeft.Copy()
width -= 2 * (insideTL.X - tl.X) width -= 2 * (insideTL.X - tl.X)
height -= 2 * (insideTL.Y - tl.Y) height -= 2 * (insideTL.Y - tl.Y)
@ -41,7 +41,7 @@ func (s shapeCircle) GetDimensionsToFit(width, height, paddingX, paddingY float6
return diameter, diameter return diameter, diameter
} }
func (s shapeCircle) GetInsidePlacement(width, height, padding float64) geo.Point { func (s shapeCircle) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(s.Box.Width/2-width/2), s.Box.TopLeft.Y+math.Ceil(s.Box.Height/2-height/2)) return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(s.Box.Width/2-width/2), s.Box.TopLeft.Y+math.Ceil(s.Box.Height/2-height/2))
} }

View file

@ -46,7 +46,7 @@ func NewCloud(box *geo.Box) Shape {
func (s shapeCloud) GetInnerBox() *geo.Box { func (s shapeCloud) GetInnerBox() *geo.Box {
width := s.Box.Width width := s.Box.Width
height := s.Box.Height height := s.Box.Height
insideTL := s.GetInsidePlacement(width, height, 0) insideTL := s.GetInsidePlacement(width, height, 0, 0)
aspectRatio := width / height aspectRatio := width / height
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
width *= CLOUD_WIDE_INNER_WIDTH width *= CLOUD_WIDE_INNER_WIDTH
@ -75,17 +75,17 @@ func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64
} }
} }
func (s shapeCloud) GetInsidePlacement(width, height, padding float64) geo.Point { func (s shapeCloud) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
r := s.Box r := s.Box
width += padding width += paddingX
height += padding height += paddingY
aspectRatio := width / height aspectRatio := width / height
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY { if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+padding/2)) return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+paddingY/2))
} else if aspectRatio < CLOUD_TALL_ASPECT_BOUNDARY { } else if aspectRatio < CLOUD_TALL_ASPECT_BOUNDARY {
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+padding/2)) return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+paddingY/2))
} else { } else {
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+padding/2)) return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+paddingY/2))
} }
} }

View file

@ -25,7 +25,7 @@ func NewOval(box *geo.Box) Shape {
func (s shapeOval) GetInnerBox() *geo.Box { func (s shapeOval) GetInnerBox() *geo.Box {
width := s.Box.Width width := s.Box.Width
height := s.Box.Height height := s.Box.Height
insideTL := s.GetInsidePlacement(width, height, 0) insideTL := s.GetInsidePlacement(width, height, 0, 0)
tl := s.Box.TopLeft.Copy() tl := s.Box.TopLeft.Copy()
width -= 2 * (insideTL.X - tl.X) width -= 2 * (insideTL.X - tl.X)
height -= 2 * (insideTL.Y - tl.Y) height -= 2 * (insideTL.Y - tl.Y)
@ -41,7 +41,7 @@ func (s shapeOval) GetDimensionsToFit(width, height, paddingX, paddingY float64)
return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight) return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight)
} }
func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point { func (s shapeOval) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
// showing the top left arc of the ellipse (drawn with '*') // showing the top left arc of the ellipse (drawn with '*')
// ┌──────────────────* ┬ // ┌──────────────────* ┬
// │ * │ │ry // │ * │ │ry
@ -60,7 +60,7 @@ func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point
// see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo // see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo
r := rx * ry / math.Sqrt(math.Pow(rx*sin, 2)+math.Pow(ry*cos, 2)) r := rx * ry / math.Sqrt(math.Pow(rx*sin, 2)+math.Pow(ry*cos, 2))
// we want to offset r-padding/2 away from the center // we want to offset r-padding/2 away from the center
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-padding/2)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-padding/2))) return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-paddingX/2)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-paddingY/2)))
} }
func (s shapeOval) Perimeter() []geo.Intersectable { func (s shapeOval) Perimeter() []geo.Intersectable {