Improving Radial Pinch

This commit is contained in:
Lars Brubaker 2023-10-25 19:05:11 -07:00
parent 552eab94a7
commit 381cddf825
2 changed files with 56 additions and 5 deletions

View file

@ -199,7 +199,10 @@ namespace MatterHackers.MatterControl.DesignTools
var enclosingCircle = SourceContainer.GetSmallestEnclosingCircleAlongZ();
var rotationCenter = enclosingCircle.Center + RotationOffset;
var horizontalOffest = LinearHorizontalOffset.GetOffsetPath(enclosingCircle.Radius + RotationOffset.Length, size);
var maxRadius = enclosingCircle.Radius + RotationOffset.Length;
var horizontalOffset = new FlattenCurves(LinearHorizontalOffset.GetOffsetPath(maxRadius, size));
var xAtYInterpolator = new XAtYInterpolator(horizontalOffset);
var pinchedChildren = new List<IObject3D>();
@ -233,13 +236,15 @@ namespace MatterHackers.MatterControl.DesignTools
}
var positionXy = new Vector2(position) - rotationCenter;
if (true)
var fromLine = true;
if (fromLine)
{
positionXy *= Easing.Quadratic.InOut(ratio);
//positionXy *= horizontalOffset.GetXAtY(position.Z) / maxRadius;
positionXy *= xAtYInterpolator.Get(position.Z) / maxRadius;
}
else
{
//positionXy *= horizontalOffest.GetXAtY(positionXy.Y - bottom);
positionXy *= Easing.Quadratic.InOut(ratio);
}
positionXy += rotationCenter;
transformedMesh.Vertices[i] = new Vector3Float(positionXy.X, positionXy.Y, position.Z);
@ -306,4 +311,50 @@ namespace MatterHackers.MatterControl.DesignTools
}
}
}
internal class XAtYInterpolator
{
private double bottom;
private double top;
private int numberOfSegments;
private double[] offsetAtY;
public XAtYInterpolator(IVertexSource inputCurveIn)
{
var inputCurve = new VertexStorage(inputCurveIn);
var bounds = inputCurve.GetBounds();
bottom = bounds.Bottom;
top = bounds.Top;
numberOfSegments = 100;
offsetAtY = new double[numberOfSegments + 1];
for (int i = 0; i < numberOfSegments + 1; i++)
{
var y = bottom + (top - bottom) * i / numberOfSegments;
offsetAtY[i] = inputCurve.GetXAtY(y);
}
}
internal double Get(double y)
{
// check if we are bellow the bottom
if (y <= bottom)
{
return offsetAtY[0];
}
// check if we are above the top
if (y >= top)
{
return offsetAtY[numberOfSegments];
}
// find the segment we are in
var segment = (int)((y - bottom) / (top - bottom) * numberOfSegments);
// lerp between the two points
var ratio = (y - bottom) / (top - bottom) * numberOfSegments - segment;
return offsetAtY[segment] * (1 - ratio) + offsetAtY[segment + 1] * ratio;
}
}
}

@ -1 +1 @@
Subproject commit fc0be85c4d05613470865d548f88c16e1c38b6b2
Subproject commit d7786240ef49ae59929da73363e8a17311941aef