using System.Numerics;
|
|
|
|
namespace Smoll {
|
|
|
|
struct Transform2D {
|
|
public Complex position;
|
|
public Complex anchor;
|
|
public float angle;
|
|
public Complex scale;
|
|
}
|
|
|
|
sealed class Transform2DComponent : Component {
|
|
public Transform2D transform;
|
|
|
|
public Transform2DComponent() {
|
|
transform = new Transform2D();
|
|
transform.scale = Complex.ImaginaryOne + 1;
|
|
}
|
|
|
|
public Transform2D AbsoluteTransform() {
|
|
var up = owner.parent;
|
|
do {
|
|
if(up == null) return transform;
|
|
|
|
var component = up.GetComponent<Transform2DComponent>();
|
|
if(component != null) {
|
|
Transform2D combined = component.AbsoluteTransform();
|
|
var unscaled_pos =
|
|
(combined.position + transform.position - combined.anchor)
|
|
/(Complex.Exp(Complex.ImaginaryOne * combined.angle) - combined.anchor);
|
|
var normalized_pos = unscaled_pos/unscaled_pos.Magnitude;
|
|
combined.position = unscaled_pos.Magnitude*(transform.scale.Real*normalized_pos.Real + transform.scale.Imaginary*normalized_pos.Imaginary*Complex.ImaginaryOne);
|
|
var unscaled_anchor =
|
|
(combined.position + transform.anchor - combined.anchor)
|
|
/(Complex.Exp(Complex.ImaginaryOne * combined.angle) - combined.anchor);
|
|
var normalized_anchor = unscaled_anchor/unscaled_anchor.Magnitude;
|
|
combined.anchor = unscaled_anchor.Magnitude*(transform.scale.Real*normalized_anchor.Real + transform.scale.Imaginary*normalized_anchor.Imaginary*Complex.ImaginaryOne);
|
|
combined.scale *= transform.scale;
|
|
combined.angle += transform.angle;
|
|
return combined;
|
|
}
|
|
up = up.parent;
|
|
} while(true);
|
|
}
|
|
}
|
|
|
|
}
|