Morpholib

Latest version: v0.9.0

Safety actively analyzes 624712 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 2

0.8.1

Changes
- The default stroke width used for the `drawIn()` Path action was changed from 3 to 2.
- Frame tweening now checks for equal subfigure counts and throws an error if attempting to tween two Frames of unequal subfigure counts.

New Features
- All figures now possess a `modifier` attribute which can be set to a function that will modify (a copy of) the figure at draw time, enabling an organic way for a figure's state to change dynamically based on another figure's state.
- Added `FigureArray` which is like `Frame` but can be used to more easily create and manipulate figures laid out in a grid pattern.
- Added new `roundedRect()` function to `morpho.shapes` that returns a Spline in the shape of an (approximate) rounded rectangle---that is, a rectangle with circular arc corners.
- Added `substagger` option to the `drawIn()` MultiPath/MultiSpline action enabling more control over the time offset in animating adjacent glyphs being drawn in in (for example) a LaTeX figure.
- Added `popIn()` and `popOut()` actions for Paths and Splines and their Multi variants.
- New `pulse()` action for Point figures which causes a point to grow and then shrink again. Useful for drawing the viewer's eye to the point.
- New `waitUntilSec()` Animation method acts like `waitUntil()` but the inputted target time is in units of seconds instead of frames.
- New `timelineCoord()` Animation method which converts true playback times into local animation timeline coordinates, taking into account any animation delays. Kind of like an inverse `seconds()` method.
- New `listselect()` function added to `morpho.tools.basics` which takes a list and a collection of indices or index slices and returns a dict mapping individual indices to list elements.

Improvements
- `Frame.merge()` can now take an optional `beforeFigure` parameter that functions similar to how `beforeActor` and `beforeLayer` work for `Layer.merge()` and `Animation.merge()`.
- `Frame.setName()` now returns the Frame instance that calls it.
- Frame figures (and their derivatives like MultiFigures) are now considered BoundingBoxFigures, and so support methods like `box()`, `left()`, `right()`, `center()`, etc.
+ Note that these methods will fail if the Frame contains any subfigures that are not BoundingBoxFigures.
- Added optional `select` parameter to `Frame` and `MultiFigure` fade actions as well as MultiPath/MultiSpline `drawIn()` action.
- Added optional `straight` keyword parameter to Spline's and SpaceSpline's `close()` method which if set to `False` closes the spline not with a straight line segment but according to the current state of its tangent handles.
- Added `dash` and `dashOffset` attributes to Point figures.
- Multiactions can now be run from unregistered actions.
+ Previously to apply an actor action across a list of actors, the action had to be named and registered so that it could be accessed via the command `morpho.action.actionname(actorlist, ...)`. But now this functionality is available to unregistered (e.g. user-made) actions via the syntax `morpho.action(mycustomaction, actorlist, ...)`
- Optimized subaction substaggering.
- Implemented a collective subaction command `morpho.subaction` analogous to `morpho.action`.
- Streamlined the interface for multiactions and multisubactions.
+ The collective action commands `morpho.action.actionname` and `morpho.subaction.actionname` should now work on any action that is "standard", meaning the action only affects an actor by possibly modifying its current final keyfigure and/or adding new keyfigures after it; i.e. they affect only the present and future of an actor, not its past. Essentially all built-in actions are "standard" and so will work with the collective action commands.
- The `highlight()` and `flourish()` actions are now available for vanilla (i.e. non-Multi) Paths and Splines.
- The `highlight()` and `flourish()` actions can now take an explicit `None` input for its `fill` parameter, which will prevent the actions from modifying the `fill` parameter.
- Implemented `toPolygon()` and `toPath()` for the Ellipse class.
- All BoundingBoxFigures now possess a `boxDimensions()` method that returns both box width *and* box height as a tuple.
- `finitizeDelays()` can now accept a delay value of zero.
- If `waitUntil()` and `waitUntilSec()` throw an error for trying to wait a negative amount of time, they now report the undershot time in seconds in addition to frames.
- Optimized Actor `now()` method with caching so it's more efficient if called multiple times at the same point on the timeline.

Bug Fixes
- Fixed a bug with setting subfigure names for MultiFigures.
- Fixed a bug with Frame `fadeOut()` action in which the final keyfigure may not be set to be invisible if `select` is used to select a proper subset of the subfigures.
- Fixed a bug with MultiFigure subactions where using it with no substaggering *nor* special selections resulted in transitions being ignored.

0.8.0

Changes
- Overhauled how `Frame` figures are tweened.
+ Subfigure transitions are now ignored, and the toplevel transition of the Frame figure is used for everything. This behavior can still be circumnavigated by incorporating transitions directly into subfigure tween methods via a new function `morpho.transitions.incorporateTransition()`.
- The `box()` methods for Images and Text now account for transformation attributes by default.
- Tween method splitters have been reworked.
+ Instead of taking only the tsplit value, they must now take three additional required inputs: `beg`, `mid`, and `fin` representing the three keyfigures involved in a split.
+ They also no longer should return the two halves of the split tween method, but instead modify the tween methods in place (via `beg`, `mid`, and `fin`).
+ This change will only affect you if you have defined custom splitters. If you haven't (or you don't know what that means), nothing will have changed for you.
- Assigning a value directly to the `figures` attribute of a `Frame`-like figure now automatically typecasts it into a python list.

New Features
- Frame and MultiFigure actors now support a `subaction` property that allows you to apply certain actor actions along subfigures as well as specifying a `substagger` parameter to control time offsets between them.
+ e.g. `multispline.subaction.growIn(30, substagger=5)`
+ The `substagger` option has been incorporated into `fadeIn()` and `fadeOut()`, meaning it is unnecessary (and also not recommended) to use `subaction` to apply those particular actions to subfigures.
+ You can also use `subaction` with unregistered actor actions by directly calling it with this syntax:
python
myfilm.subaction(myCustomAction, ...)

+ Note: This feature has only been designed to work for actions that only need access to the final keyfigure of an actor and only modifies the actor by appending new keyfigures to the end of its timeline. These include actions like `fadeIn/Out()` and `growIn()/shrinkOut()` but notably not `rollback()` since it needs access to the first keyfigure.
- Added `popIn/Out()` actions for the `Ellipse` class.
- Implemented new `Actor.zip()` static method that takes a list of actors and "zips" them into a single `Frame` actor (a.k.a. a "Film").
- Implemented `drawIn()` actor action for MultiPaths and MultiSplines which allow for the actor to be "drawn in" Manim-style.
+ It's still a bit experimental and not well tested yet, and the API may still change. Use at your own risk.
- Added `incorporateTransition()` function to `morpho.transitions` which directly incorporates a transition function into a tween method.
- `FlowField` now supports multiple different offsets.
- Added `atFrame` optional keyword to `wait()` method.

Improvements
- Added `tickOffset` attribute to the `Track` class and `mathaxes()`.
- Added `dash` attributes to the various Elliptical classes in `morpho.shapes`.
- `rect()` can now take an Actor/Figure as input at it will infer a box from its bounding box (if possible).
- The various box methods within `morpho.tools.basics` now typecast Actors/Figures into boxes via their bounding boxes (if possible).
- `Frame.sub[]` now correctly transfers any subfigure names, and `Frame.cut[]` removes subfigure names from the dict.
- Indices to `partition()` can now also be supplied as individual positional arguments instead of packaged into a list.
- Additional keyword values supplied to the `highlight()` actor action for MultiPaths/MultiSplines are now set as attributes of the affected subpaths.
- `enboxHighlight()` has been renamed `enboxFlourish()`, though the old name is still usable.
- A closed path will now have a seamless connection between its ending and starting nodes.
- Added `spacing` option to `quadgrid()`.
- Improved function tweening (homotopy tweening). Tweening can now occur between numeric-valued functions of arbitrary input signatures as long as the starting and ending signatures match.
- Added `convertCoordsFrom()` method to `Camera` class.
+ It's identical to `convertCoords()`, but it reverses the roles of `self` and `other`.
- Added `dimensions()` method to `Camera` class which returns width and height of the viewbox all at once as a tuple.
- Added `aspectRatioWH` property to the `Animation` class.

Bug Fixes
- Setting `tipSize` property for `MultiPaths` and `MultiSplines` will now work even if head and tail sizes differ.
- `SpaceFrame` can now be initialized using keyword arguments to create named subfigures just like the vanilla `Frame` class can.
- Fixed a bug with `MultiImage/MultiText` `box()` method.
- Fixed a very old bug with `Path.concat()`.

0.7.1

Changes
- LaTeX code is now cached using template and preamble too.
+ As a result, all prior LaTeX caches will be invalidated after updating to this version, so it's a good idea to clear them out so they don't waste space.
- SciPy is now a soft requirement for Morpho (it's needed to use the new `FlowField` gadget, but nothing else currently). SciPy won't be automatically installed when Morpho is updated, but can be manually installed with the command `pip install scipy`.
- `SpacePolygon` default border color is now white, bringing it into alignment with what 2D `Polygon` does.
- Setting/getting attributes of a MultiFigure that are not top-level will now implicitly use `.all` to set/get it from all subfigures instead of just the first subfigure.

New Features
- 3D LaTeX is now supported via the `morpho.latex.parse3d()` function.
- Individual glyphs within a LaTeX figure can now be selected by character:
python
myTex.select[morpho.latex.matches(r"\pi")].set(fill=[1,0,0])

+ Note that this feature isn't perfect and will sometimes fail, particularly for symbols that are actually made up of two glyphs (e.g. `\implies`) or when a symbol may subtly change from its base version (e.g. by superscripting, so for example the "2" in `x^2` has to be matched with `^2` instead of just `2`).
- Added `matches()` function to `morpho.color` which checks if two normalized RGB triplets are close enough to be regarded as the same color.
- New `FlowField` gadget allows for the creation of streamer fields.
+ **Note:** This requires `scipy` to be installed.
- New `highlight()` and `flourish()` actor actions for LaTeX figures (i.e. `MultiPath`/`MultiSpline`).
- New `enboxHighlight()` function added to `morpho.gadgets` that does the same as `enbox()` but then immediately deboxes.
- New `locatorModifier` property to the Animation class that can be set to a function which will be applied to clicked locations before printing them to the console.
- New `mathaxes3d()` function added to `morpho.grid`.
- New functions `wedge()` and `tilt()` added to `morpho.matrix`.
- Frames can be partitioned into chunks and recombined with new `partition()` and `combine()` methods.
+ Can be useful in more precisely controlling LaTeX morphs.
- The subfigures copied when tweening between two MultiFigures with different subfigure counts can now be controlled using a new `subpool` property.
- Spiral Tween is now supported for many space figures.
+ e.g. `SpacePoint`, `SpacePath`
- `Polygon.toPath()` and `Pie.toPath()` are now implemented.
- New `Frame.cut[]` feature behaves like `.sub[]` except it also deletes the extracted subfigures from the `Frame`-like figure that called it.
- Subfigure attributes of MultiFigures can now be modified en masse with in-place operations like `+=` via the properties `.iall` and `.iselect[]`.

Improvements
- Optimized animation playback/rendering, meaning they should play smoother and render faster particularly for animations containing a lot of complex figures that aren't moving.
- Functions in `morpho.gadgets` that require a box to be given can now optionally take a Figure or Actor object as input instead and its bounding box will be used as the box (assuming it can be computed).
- New `morpho.text.space()` function can be used to insert spaces as individual subfigures in paragraphs. Can help control text spacing in a paragraph.
- Many `grid` submodule figures are now optionally accessible from `shapes`
+ e.g. `morpho.shapes.Path()` now works.
- MultiFigure `.select[]` feature can now take multiple index ranges.
+ e.g. `mytex.select[1:4, 6]`
- MultiFigure `.all` and `.select[]` have been made more robust and better behaved in general.
+ Specifically, calling `.set()` after either one is guaranteed to return the original `Frame`-like figure that invoked `.all` or `.select[]`.
- `morpho.tools.basics.totalBox()` can now accept an optional `pad` parameter.
- `padbox()` and `shiftBox()` can now optionally accept figures/actors as input and will attempt to infer their bounding boxes to use as the box.
- New `coast()` transition added to `morpho.transitions` which is identical to `glide()` except the second inflection point is now specified in terms of how far away it is from 1 instead of 0.
python
These two are equivalent:
glide(0.2, 0.7)
coast(0.2, 0.3)

- `morphFrom()` was refactored to hopefully make it work better with puppet skits.
- `morphFrom()` for LaTeX figures (i.e. `MultiPath`/`MultiSpline`) can now optionally take a list of figures/actors to morph from instead of just a single one.
- The number of subfigures in a `Frame`-like figure can be gotten more immediately using a new `numfigs` property.
- Attempting to set/get an attribute of a MultiFigure that is not top-level will now implicitly call `.all` instead of just operating on the first subfigure.
+ This makes changing, say, the transparency of a LaTeX MultiSpline more intuitive, as instead of doing `mytex.all.alpha = 0` you can just do `mytex.alpha = 0`.
- New `sel[]` feature in `morpho.tools.basics` allows for easier construction of index tuples. Identical to `numpy.s_`.
+ e.g. `sel[a:b:c] --> slice(a,b,c)`

Bug Fixes
- Fixed `SpacePath` default figure initialization.
- Fixed a bug with rendering certain empty `SpaceTrack` figures.
- Multiplying a `Mat` object by a singleton now treats a singleton np.array like `np.array(3+4j)` just like a regular complex number.
- Fixed a floating point bug that could cause paths to be drawn incorrectly.
- Fixed a bug where a background box for a Path could be drawn twice.
- Fixed a bug with drawing `MultiPath`/`MultiSpline` background boxes.
- All inputs to `basicgrid()` are now keyword only.
- Fixed a bug with passing in gradients to `mathgrid()`.
- The `tweenMethod` keyword for `mathgrid3d()` now works.
- `spacing` option for `mathgrid3d()` now exists.
- Invisible subfigures in a `SpaceFrame` will no longer be drawn.
- Conversion from 2D to 3D Paths and Polygons now copies all the non-tweenable attributes it's supposed to.
- Fixed a strange bug where 1-frame animations would sometimes crash Python when played.

0.7.0

Changes
- Added `svgelements` as a dependency. Should be automatically installed when updated thru pip.
- `Path.center()` now returns the center of the path's bounding box instead of the center of mass of its nodes. The center of mass can now instead be calculated by calling the `centroid()` method.
- Mask layers whose `visible` attribute is set to `False` are no longer applied.
- Figure delays, Layer time offsets, and Layer `start`/`end` features are now officially deprecated.
+ They're not being removed yet, but I will no longer be making much effort to support them such as bug fixes or ensuring they remain compatible with new features going forward.

New Features
- New actors can now be automatically created and affixed to a layer in a single line with the syntax `myactor = mylayer.Actor(myfigure)`
+ This streamlines the process of introducing new actors to the current end of the global animation timeline. Coupled with the `set()` method, new actors can be created, initialized, and affixed to a layer all in one line:
python
The return value of `Layer.Actor()` is the newly created Actor object itself
arrow = mylayer.Actor(morpho.grid.Arrow(1, 2+2j).set(width=5, color=[1,0,0], ...))

+ Placement on the timeline can still be modified by passing in the optional keyword inputs `timeOffset` or `atFrame`
python
myactor = mylayer.Actor(myfigure, timeOffset=10)
myactor2 = mylayer.Actor(myfigure2, atFrame=0)

- New `MultiSpline` figure enables Morpho to load many SVG files by calling `MultiSpline.fromsvg(filename)`
- Morpho can now parse LaTeX math code into a MultiSpline figure by calling `morpho.latex.parse(latexCode)`.
+ Note this requires you to have a LaTeX distribution installed, as well as dvisvgm.
- `PText` and physical paragraph figures have a new `toSpline()` method that converts a physical text figure into a MultiSpline.
+ Note this is still a pretty experimental feature and needs further improvement, especially for paragraphs where the output can sometimes look significantly off.
- Paths and Splines now support a `box()` method that returns the bounding box of the figure.
+ Also included are side methods `left()`, `right()`, `top()`, `bottom()` and corner methods `northwest()`, `southwest()`, `southeast()`, `northeast()`.
- Paths and Splines now support background boxes via setting the attributes `background`, `backAlpha`, and `backPad`.
- Paths and other Path-like figures have a new `dashOffset` attribute.
- New Spline `autosetHandles()` method converts Splines into Catmull-Rom Splines by modifying the tangent handles.
- `Spline.fimage()` now works.
- Paths and Splines now support an `align` property that works similarly to `align` for Images and Text figures. Mainly useful for aligning MultiSplines representing a math expression.
- Paths and Splines can now be "backstroked", meaning the stroke will appear behind the fill. This is done by setting a *negative* `width` value: `mypath.width = -6`.
- Arrows now have a `vector` property which returns/sets the tail-to-head vector:
python
myarrow.vector Returns myarrow.head - myarrow.tail
myarrow.vector = 2+3j Equivalent to myarrow.head = myarrow.tail + 2+3j

- New `morpho.grid.basicgrid()` function produces a grid better suited for when you don't need the grid to morph.
- `paragraph()` now has `xbuf` and `ybuf` optional inputs that work like a size-independent `xgap` and `ygap` in which the gap spacing is specified in units relative to the font size.
- New `select` property for `Frame` figures allows modifying all the attributes of a subset of subfigures.
+ Example: `myframe.select[2:5].set(pos=1+2j)` modifies the `pos` attribute of subfigures 2 thru 4 (inclusive).
+ A boolean-valued choice function can also be given to `select[]` to only select subfigures meeting a certain criterion:
python
myframe.select[lambda subfig: subfig.alpha == 0].set(alpha=1)

+ Note that `select[]` cannot be used to extract a sub-Frame. For that, use the `sub[]` property.
- New `sub` property for `Frame` figures allows extracting a subset of subfigures as a new `Frame` figure. The input syntax is the same as for `select[]`, but the returned value is a new `Frame` consisting of copies of the selected subfigures.
- Position of a keyfigure in an Actor's timeline can now be obtained by calling `myactor.timeof(keyfigure)`.
- New `morphFrom()` actor action provides an easy way to morph a copy of an actor into a new actor. Particularly useful when animating a new math formula morphing out of another math formula.
- Added various box functions to `morpho.tools.basics`:
+ `padbox()` adds horizontal/vertical padding to a box.
+ `totalBox()` computes the total bounding box of a list of boxes.
+ `shiftBox()` translates a box by a given vector.

Improvements
- The `endDelay()` and `endDelayUntil()` methods of the `Animation` class now have aliases `wait()` and `waitUntil()`.
- Non-physical paragraphs are now easier to initialize as providing `windowShape` is optional in most use cases now.
- Text array inputs to `paragraph()` are now much more tolerant, supporting a mix of `Text` figures, strings, and sublists.
+ Example:
python
morpho.text.paragraph(["Hello", morpho.text.Text("World", color=[1,0,0])], ...)

- `Actor.key[]` can now be accessed by object as well as by stack index enabling syntax like
python
myactor.key[keyfig] = newkeyfig
del myactor.key[keyfig]

- Paths/Splines with deadends are now properly tweenable.
- Path/Spline slicing now handles deadends correctly.
- `enbox()`, `encircle()`, and `crossout()` functions can now take an optional `pad` input to apply padding to the given box.
- Added new option for outlined path rendering.
- The `origin` attribute for Paths and Splines can now be accessed/modified using the alias `pos`, making them feel similar to Image and Text figures in that regard.
- Methods can now be called from `Frame.all`. Useful for calling a method that will modify each subfigure in place, e.g. `myframe.all.commitTransforms()`
- `Frame.merge()` now returns `self`, enabling method chaining after a merge call.
- `Polygon` now handles drawing bad vertex values (e.g. `nan` or `inf`) better.
- Temporary directories are now generated differently when exporting an animation, removing the need to set an export signature if exporting multiple animations in parallel.

Bug Fixes
- `Frame.merge()` should now correctly handle merging another `Frame` figure.
- Zero-length space arrows are now drawn.
- Fixed visual bug with cyclic paths with arrows.
- Fixed bug with `Spline.close()`
- `Spline` spiral and pivot tween methods now correctly tween the `origin` attribute.
- `SpaceSpline.newNode()` now has `relHandles` option.
- Fixed bug in color gradient detection for Paths.
- Fixed bug in bounding box methods for physical Text figures.
- Stroke widths below 0.5 are now ignored. This should fix some visual bugs.
- Fixed visual bug for Splines whose tangent handles were extremely close but not coincident with their positional nodes.
- Fixed bug with Paragraph tweening.

0.6.1

Changes
- If unspecified at construction, the `yradius` attribute of `morpho.shapes.Ellipse` now copies `xradius` instead of defaulting to `1`.
- If unspecified at construction, the `theta1` attribute of `morpho.shapes.EllipticalArc` now defaults to `theta0 + 2pi` instead of just `2pi`.

New Features
- Implemented features enabling a simplified workflow for creating longer-form animations.
+ Actors and Layers now have access to the global animation timeline, removing the need to use the idiom `time = mation.lastID()` to insert new actors/keyframes at an animation's current end.
+ `newendkey()` can now be called with no arguments to create a new keyframe at the global animation's end. Equivalent to `newkey(mation.lastID())`.
* Time offsets can be made with respect to the end of the global animation timeline by passing `glob=True` into `newendkey()`:
python
myactor.newendkey(20, glob=True) Make new key 20 frames after current final animation frame.

+ Layers have a new method `affix()` that behaves identically to `append()` except it always appends to the end of the global animation timeline instead of just the layer's local timeline.
- Puppet skits are now easier to make since Actors now have a new `now()` method that returns the current figure the actor is, at the current global animation time index.
- Camera figures now possess a `rotation` attribute that rotates the view counter-clockwise about the current view's center.
+ New `Camera.rotate()` method facilitates this.
- New tween methods `tweenZoomWithMultiplier()` and `tweenZoomJump()` for `Camera` class
+ Enable a camera to change its zoom level in the middle of a zoom tween.
+ Example:
python
Camera will now temporarily zoom out by a factor of 2 in the
middle of a zoom tween.
cam.tweenMethod = morpho.Camera.tweenZoomJump(2)

- Added named side/corner methods to `Image` and `Text` classes and their derivatives.
+ The methods are `left()`, `right()`, `top()`, `bottom()`, `northwest()`, `southwest()`, `southeast()`, and `northeast()`.
+ They return the corresponding position of the figure's physical bounding box.
- Added `glide()` transition function to `morpho.transitions`.
- New `all` property of Frames allows an attribute of all subfigures to be accessed/modified in a single line
+ Example: `myframe.all.color = (1,0,0)`
- Path/Spline `start` and `end` attributes can now go outside the interval [0,1] whereby they will be interpreted cyclically.
- Arrows can now be placed so that the base of the triangle occurs at the path endpoints instead of its tip. This applies for both Paths and Arrow figures.
- New `Path.center()` method returns the center of mass of all nodes in the path.
- Added geometry properties `eccentricity`, `majorRadius`, and `minorRadius` to `morpho.shapes.Ellipse` and also enabled the transformation attributes `rotation` and `transform`.
- `EllipticalArc` now supports the `growIn/shrinkOut()` actor actions.
- Physical and non-physical text paragraphs now possess `width()` and `height()` methods that return the width or height of the paragraph's physical bounding box.

Improvements
- `Frame.merge()` can now handle a raw Figure-type input by interpreting it as a Frame containing a single subfigure.
python
These are now equivalent:
myframe.merge(myfig)
myframe.merge(morpho.Frame([myfig]))

- Detection of (near-)singular matrix transformations is now done more smartly to avoid certain false-positive detections.
- `Camera` and `SpaceCamera` are now accessible from the base morpho namespace: `morpho.Camera` and `morpho.SpaceCamera`.

Bug Fixes
- Setting `tipSize` while `headSize != tailSize` will no longer throw an error.
- The `seamless` optional argument for `newendkey()` is now keyword-only just like its counterpart in `newkey()`.
- For multifigures (`MultiImage`, `MultiText`, etc.), caller-returning methods like `newSource()` that return the figure that called them now correctly return the multifigure object itself, instead of the subfigure, when called directly from the multifigure object.
python
multimg.newSource(...) Correctly returns `multimg` instead of `multimg.figures[0]`

- `box()` method is now correctly disabled for spacefigure classes that used to possess them.
- Fixed a bug with path tweening that could occur if the starting and ending path node counts differed by exactly one node.
- Fixed a bug for 2-node paths in which arrow tip directions would get mixed up if the tip sizes were very large in proportion to the path length.

0.6.0

Changes
- Changed the default behavior of `newkey()` and `newendkey()` when inserting a keyfigure between two existing keyfigures. See below for more info.
+ As a result, the built-in transition function `instant()`/`step()`/`jump()` has been disabled. Instead, set `static=True` or use `tweenMethod=tweenInstant` to achieve the same effect.
- The `figures` parameter in the `Frame` constructor is now positional-only to facilitate naming subfigures (see below).

New Features
- When inserting a new keyfigure between existing keyfigures in an actor using `newkey()` or `newendkey()`, Morpho will now attempt to integrate the new intermediate keyfigure seamlessly into the animation by modifying the transition method of the prior and inserted keyfigures.
+ This behavior can be suppressed by passing in the optional keyword argument `seamless=False`.
- Reworked how retrieving Figure attributes works which should make Morpho run faster particularly for animations containing many actors.
- Subpaths can be extracted from paths using the new `segment()` method or by using Python slice syntax: `mypath[a:b]`
+ This is also true of splines, though it should be considered experimental at this stage.
- `Spline.node()` can now optionally accept in/outhandles as well, making it possible to fully specify a spline's behavior at a node in one line of code.
- `Frame` (and `Frame`-like) figures can now have their component figures assigned names accessible using attribute syntax: `myframe.mypath`
+ This can be done at construction time with the syntax `Frame(name1=figure1, name2=figure2, ...)` or afterward with the `setName()` method.
+ `mathaxes()` now names its component axes `xaxis` and `yaxis` so they can be easily accessed/modified after construction.
- `Frame` figure overall position can now be modified with a new built-in `origin` attribute.
- `Frame` figures now support the basic actor actions `fadeIn/Out()` and `rollback()`.
- `paragraph()` function can now optionally take a Layer/Camera object and/or Animation object as inputs to its required `view` and `windowShape` parameters.
+ This helps streamline the common pattern where `view` is a given layer's latest camera view, and the `windowShape` comes from an `Animation` object's `windowShape`:
python
These are now equivalent:
paragraph(textarray, mylayer, animation, ...)
paragraph(textarray, mylayer.camera.last().view, animation.windowShape, ...)

+ This typecasting also applies to virtually every other `view, windowShape` parameter pair in the methods of the `morpho.text` submodule.
- `Gradient` objects can be sliced using Python slice syntax: `mygrad[a:b]`
+ They are also now reversible using the new `reverse()` method.
- Added `rotation2d()` and `scale2d()` functions to `morpho.matrix`.
- Locator layers now print coordinates to the screen in the form `x+yj` instead of tuple form `(x,y)` to make it easier to copy and paste them into code.
- `Point` actors now support the `growIn()` and `shrinkOut()` actions.
- Added new `blink()` actor action to all figure types. Causes the actor visibility to blink off and on a specified number of times.
- Added coordinate conversion methods to `Camera` class to make converting between different camera coordinate systems easier.

Bug Fixes
- Fixed a bug where outlined paths having dash patterns with very short dash steps would cause a crash.
+ Fixed a similar bug with `Track` objects with extremely small tick spacings.
- Fixed a bug where zero-length `Axis` figures would cause a crash if drawn.
- `Spline.toPath()` will now correctly copy over the spline's dash pattern.
- Fixed a bug in `mathaxes()` where the `tweenMethod` optional argument would be ignored.
- Fixed a bug with locator layers where clicking the screen after the animation has stopped at its final frame would capture the location of the click according to the *first* frame of the animation when replayed. This could cause issues if the starting and ending frames of the animation had differing camera views.
- Fixed a bug where changing an animation's frame rate with `newFrameRate()` would cause the playback timing to sometimes fall out of sync with the original if the original animation contained many delays.
- Fixed an obscure bug that could occur for paths with extremely thin widths. Path widths below 0.5 pixels are no longer drawn.
- Suppressed a numpy warning that would be thrown in `Spline.commitTransforms()`
- (fixed in 0.5.1) Fixed a bug where rotating an `Image` figure after having scaled its `width` attribute unlinked from its `height` would cause the image to be horizontally scaled *after* rotation, instead of before.
- (fixed in 0.5.1) Tickmarks of `mathaxes()` are now centered better.

Page 1 of 2

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.