0
# Core Objects
1
2
Foundation classes for multi-dimensional interpolation that work with any arithmetic objects. These objects form the mathematical core of MutatorMath and can be used independently of UFO-specific functionality.
3
4
## Capabilities
5
6
### Location Objects
7
8
N-dimensional coordinate representation with full arithmetic support. Location objects behave like numbers and can be added, subtracted, multiplied, and divided. They store axis names as keys and coordinate values as values.
9
10
```python { .api }
11
class Location(dict):
12
"""
13
N-dimensional location object subclassed from dict.
14
15
- key is dimension or axis name
16
- value is the coordinate
17
- Location objects behave like numbers
18
- If a dimension is missing, assume it is zero
19
"""
20
def __init__(self, **kwargs):
21
"""Create location with axis=value pairs."""
22
23
def isOrigin(self) -> bool:
24
"""Check if location is at origin (all values are 0)."""
25
26
def isOnAxis(self) -> bool:
27
"""Check if location is on-axis (only one dimension != 0)."""
28
29
def isAmbivalent(self, dim=None) -> bool:
30
"""Check if location has both positive and negative values."""
31
32
def expand(self, axisNames):
33
"""Expand location with zero values for all axes in axisNames not already present."""
34
35
def copy(self) -> Location:
36
"""Return a copy of this location."""
37
38
def getActiveAxes(self) -> list:
39
"""Return list of axis names which are not zero."""
40
41
def getType(self, short=False) -> str:
42
"""Return string describing location type: origin, on-axis, off-axis, etc."""
43
44
def asString(self, strict=False) -> str:
45
"""Return location as formatted string."""
46
47
def asDict(self) -> dict:
48
"""Return location as plain dictionary."""
49
50
def asSortedStringDict(self, roundValue=False) -> dict:
51
"""Return location as sorted string dictionary."""
52
53
def asTuple(self) -> tuple:
54
"""Return location as tuple of (axis, value) pairs, sorted alphabetically."""
55
56
def fromTuple(self, locationTuple):
57
"""Read coordinates from tuple of (axis, value) pairs."""
58
59
def strip(self):
60
"""Remove axes with zero values."""
61
62
def common(self, other) -> Location:
63
"""Return location with axes common to both locations."""
64
65
def split(self) -> tuple:
66
"""Return (x, y) tuple for ambivalent locations."""
67
68
def spliceX(self) -> Location:
69
"""Return location with X values from split coordinates."""
70
71
def spliceY(self) -> Location:
72
"""Return location with Y values from split coordinates."""
73
74
def distance(self, other=None) -> float:
75
"""Calculate distance to other location or origin."""
76
77
def sameAs(self, other) -> bool:
78
"""Check if location is same as other location."""
79
80
def transform(self, transformDict):
81
"""Transform location using transformation dictionary."""
82
```
83
84
#### Location Arithmetic Operations
85
86
```python { .api }
87
def __add__(self, other) -> Location:
88
"""Add two locations or location and number."""
89
90
def __sub__(self, other) -> Location:
91
"""Subtract two locations or location and number."""
92
93
def __mul__(self, other) -> Location:
94
"""Multiply location by number or another location."""
95
96
def __truediv__(self, other) -> Location:
97
"""Divide location by number or another location (Python 3 division)."""
98
99
def __lt__(self, other) -> bool:
100
"""Compare locations for sorting."""
101
```
102
103
#### Location Usage Examples
104
105
```python
106
# Create locations
107
loc1 = Location(weight=100, width=75)
108
loc2 = Location(weight=900, width=125)
109
110
# Arithmetic operations
111
middle = (loc1 + loc2) / 2 # Location(weight=500, width=100)
112
offset = loc2 - loc1 # Location(weight=800, width=50)
113
114
# Check properties
115
print(loc1.isOrigin()) # False
116
print(loc1.onAxis()) # False (has multiple non-zero dimensions)
117
118
# Expand to include new dimensions
119
loc1.expand(Location(contrast=0)) # Adds contrast dimension
120
```
121
122
### Mutator Objects
123
124
Core interpolation engine that calculates instances from masters using piecewise linear interpolation. Mutator objects store master data and provide instance generation capabilities.
125
126
```python { .api }
127
class Mutator(dict):
128
"""
129
Main interpolation class for calculating instances from masters.
130
Subclassed from dict to store master data.
131
"""
132
def __init__(self, neutral=None):
133
"""Create mutator with optional neutral master."""
134
135
def makeInstance(self, location, bend=True) -> any:
136
"""
137
Calculate interpolated instance at given location.
138
139
Parameters:
140
- location: Location object specifying coordinates
141
- bend: bool, whether to apply bending transformations
142
143
Returns:
144
- Interpolated object of same type as masters
145
"""
146
147
def getInstance(self, aLocation, axisOnly=False, getFactors=False):
148
"""
149
Get instance with optional factor information.
150
151
Parameters:
152
- aLocation: Location object
153
- axisOnly: bool, use only on-axis masters
154
- getFactors: bool, return factors along with instance
155
156
Returns:
157
- Instance object or (instance, factors) tuple
158
"""
159
160
def setNeutral(self, aMathObject, deltaName="origin"):
161
"""Set the neutral master object with optional delta name."""
162
163
def getNeutral(self) -> any:
164
"""Get the neutral master object."""
165
166
def setBias(self, location):
167
"""Set the bias location for interpolation."""
168
169
def getBias(self) -> Location:
170
"""Get the bias location."""
171
172
def setBender(self, bender):
173
"""Set bender object for non-linear transformations."""
174
175
def addDelta(self, location, aMathObject, deltaName=None, punch=False, axisOnly=True):
176
"""
177
Add a delta master at specified location.
178
179
Parameters:
180
- location: Location object for this master
181
- aMathObject: Master object (must support math operations)
182
- deltaName: Optional name for this delta
183
- punch: bool, force addition even if location exists
184
- axisOnly: bool, restrict to on-axis deltas
185
"""
186
187
def getAxisNames(self) -> list:
188
"""Get list of all axis names used in this mutator."""
189
190
def collectLocations(self) -> list:
191
"""Collect all locations from masters."""
192
193
def getFactors(self, aLocation, axisOnly=False, allFactors=False) -> dict:
194
"""
195
Get interpolation factors for given location.
196
197
Parameters:
198
- aLocation: Location object
199
- axisOnly: bool, use only on-axis masters
200
- allFactors: bool, return all factors including zero
201
202
Returns:
203
- dict: Mapping of delta names to factors
204
"""
205
```
206
207
#### Mutator Builder Function
208
209
```python { .api }
210
def buildMutator(items, axes=None, bias=None) -> tuple[Location, Mutator]:
211
"""
212
Build a mutator with (location, obj) pairs.
213
214
Parameters:
215
- items: List of (Location, object) tuples defining masters
216
- axes: Optional axis definitions for bending
217
- bias: Optional bias location (auto-calculated if None)
218
219
Returns:
220
- Tuple of (bias_location, mutator) ready for interpolation
221
"""
222
```
223
224
#### Mutator Usage Examples
225
226
```python
227
from mutatorMath.objects.mutator import buildMutator
228
from mutatorMath.objects.location import Location
229
230
# Define masters with (location, value) pairs
231
masters = [
232
(Location(weight=100), 10), # thin master
233
(Location(weight=900), 100), # bold master
234
(Location(weight=100, width=75), 8), # thin condensed
235
(Location(weight=900, width=125), 120) # bold extended
236
]
237
238
# Build mutator
239
bias, mutator = buildMutator(masters)
240
241
# Generate instances
242
thin_normal = mutator.makeInstance(Location(weight=200, width=100))
243
bold_condensed = mutator.makeInstance(Location(weight=800, width=80))
244
```
245
246
### Bender Objects
247
248
Non-linear transformation objects that apply warpmaps to locations before interpolation. Benders enable custom axis mappings and non-linear behavior in design spaces.
249
250
```python { .api }
251
class Bender(object):
252
"""
253
Object for non-linear transformation of locations using warpmaps.
254
"""
255
def __init__(self, axes):
256
"""
257
Create bender with axis definitions.
258
259
Parameters:
260
- axes: Dict of axis definitions with 'map' arrays for warping
261
Format: {axisName: {'map': [(input, output), ...], ...}}
262
"""
263
264
def __call__(self, location) -> Location:
265
"""
266
Transform location using configured warpmaps.
267
268
Parameters:
269
- location: Location object to transform
270
271
Returns:
272
- Transformed Location object
273
"""
274
```
275
276
#### Bender Usage Examples
277
278
```python
279
from mutatorMath.objects.bender import Bender
280
from mutatorMath.objects.location import Location
281
282
# Define warp map for non-linear weight axis
283
axes = {
284
'weight': {
285
'map': [(0, 0), (500, 200), (1000, 1000)], # Non-linear mapping
286
'minimum': 0,
287
'maximum': 1000,
288
'default': 0
289
}
290
}
291
292
# Create bender
293
bender = Bender(axes)
294
295
# Transform locations
296
original = Location(weight=250)
297
transformed = bender(original) # Location(weight=100) - mapped via warp
298
```
299
300
### Utility Functions
301
302
Helper functions for location processing and analysis.
303
304
```python { .api }
305
def numberToString(value) -> str:
306
"""
307
Return nicely formatted string representation of numeric value.
308
309
Parameters:
310
- value: Number, tuple, or None to format
311
312
Returns:
313
- Formatted string representation
314
"""
315
316
def sortLocations(locations) -> list:
317
"""
318
Sort locations for optimal processing order.
319
320
Parameters:
321
- locations: List of Location objects
322
323
Returns:
324
- Sorted list of Location objects
325
"""
326
327
def biasFromLocations(locs, preferOrigin=True) -> Location:
328
"""
329
Calculate bias location from a set of locations.
330
331
Parameters:
332
- locs: List of Location objects
333
- preferOrigin: Whether to prefer origin as bias
334
335
Returns:
336
- Calculated bias Location
337
"""
338
339
def getLimits(locations, current, sortResults=True, verbose=False) -> list:
340
"""
341
Get limits for locations relative to current position.
342
343
Parameters:
344
- locations: List of Location objects
345
- current: Current Location
346
- sortResults: Whether to sort results
347
- verbose: Enable verbose output
348
349
Returns:
350
- List of limit information
351
"""
352
353
def noBend(loc) -> Location:
354
"""
355
Identity function for bending - returns location unchanged.
356
357
Parameters:
358
- loc: Location object
359
360
Returns:
361
- Same location object
362
"""
363
```