diff --git a/pkg/pattern/template/point.go b/pkg/pattern/template/point.go index 8fb50e2..024baad 100644 --- a/pkg/pattern/template/point.go +++ b/pkg/pattern/template/point.go @@ -32,6 +32,7 @@ type Point struct { Between *BetweenPoint `yaml:"between"` Extend *ExtendPoint `yaml:"extend"` Hide bool `yaml:"hide"` + Polar *PolarPoint `yaml:"polar"` } var ErrInvalidPointID = errors.New("type cannot be converted to a PointID") @@ -141,6 +142,11 @@ func (p Points) addSingleToPattern(id point.ID, pat *pattern.Pattern, depth int) var newPoint point.Point switch { + case templatePoint.RelativeTo != nil && templatePoint.Polar != nil: + newPoint, err = p.createPolar(id, pat, depth) + if err != nil { + return err + } case templatePoint.RelativeTo != nil: newPoint, err = p.createRelative(id, pat, depth) if err != nil { @@ -282,8 +288,52 @@ func (p Points) createExtend(id point.ID, pat *pattern.Pattern, depth int) (poin return point.NewExtendPoint(fromPoint, toPoint, offset, id), nil } +func (p Points) createPolar(id point.ID, pat *pattern.Pattern, depth int) (point.Point, error) { + templatePoint, ok := p[id] + if !ok { + return nil, ErrPointNotFound + } + + relativePointID := *templatePoint.RelativeTo + if relativePointID == id || depth > maxRecursionDepth { + return nil, ErrRelativePointRecursion + } + + relativePoint, err := p.getOrCreate(relativePointID, pat, depth) + if err != nil { + return nil, err + } + + x, y, err := templatePoint.Polar.evaluate(pat.Parameters(), p.Functions(pat)) + if err != nil { + return nil, err + } + + return point.NewRelativePoint(relativePoint). + WithXOffset(x).WithYOffset(y).MarkWith(id), nil +} + type ExtendPoint struct { From point.ID `yaml:"from"` To point.ID `yaml:"to"` Offset *Value `yaml:"offset"` } + +type PolarPoint struct { + Length *Value `yaml:"length"` + Rotation *Value `yaml:"rotation"` +} + +func (p PolarPoint) evaluate(params govaluate.MapParameters, funcs map[string]govaluate.ExpressionFunction) (x, y float64, err error) { + rotation, err := p.Rotation.Evaluate(params, funcs) + if err != nil { + return 0, 0, err + } + + length, err := p.Length.Evaluate(params, funcs) + if err != nil { + return 0, 0, err + } + + return math.Sin(rotation) * -length, math.Cos(rotation) * -length, nil +} diff --git a/spec/pattern.yaml b/spec/pattern.yaml index feb676a..0614216 100644 --- a/spec/pattern.yaml +++ b/spec/pattern.yaml @@ -44,34 +44,20 @@ components: $ref: '#/components/schemas/position' relativeTo: $ref: '#/components/schemas/pointID' + polar: + $ref: '#/components/schemas/polar' description: type: string between: - type: object - properties: - from: - $ref: '#/components/schemas/pointID' - to: - $ref: '#/components/schemas/pointID' - offset: - $ref: '#/components/schemas/expression' + $ref: '#/components/schemas/between' hide: type: bool extend: - type: object - properties: - from: - $ref: '#/components/schemas/pointID' - to: - $ref: '#/components/schemas/pointID' - offset: - $ref: '#/components/schemas/expression' - + $ref: '#/components/schemas/between' points: type: object additionalProperties: $ref: '#/components/schemas/point' - position: type: object properties: @@ -81,7 +67,22 @@ components: $ref: '#/components/schemas/expression' rotation: $ref: '#/components/schemas/expression' - + polar: + type: object + properties: + length: + $ref: '#/components/schemas/expression' + rotation: + $ref: '#/components/schemas/expression' + between: + type: object + properties: + from: + $ref: '#/components/schemas/pointID' + to: + $ref: '#/components/schemas/pointID' + offset: + $ref: '#/components/schemas/expression' line: type: object properties: @@ -95,7 +96,6 @@ components: start: $ref: '#/components/schemas/pointID' end: - type: $ref: '#/components/schemas/pointID' pointID: oneOf: @@ -103,7 +103,6 @@ components: - type: string expression: oneOf: - - type: integer - type: number - type: string diff --git a/templates/classic_trouser_block.yaml b/templates/classic_trouser_block.yaml index 4735aab..4d54aa7 100644 --- a/templates/classic_trouser_block.yaml +++ b/templates/classic_trouser_block.yaml @@ -164,14 +164,11 @@ panels: from: 13 to: 15 offset: 1.5 - r5: - position: + h5: + polar: rotation: 3*pi/4 + length: 30 relativeTo: 5 - h5: - position: - x: 30 - relativeTo: r5 hide: true 1extend: position: