diff --git a/mono/Assistance/Geometry.cs b/mono/Assistance/Geometry.cs index ce67232..13bca52 100644 --- a/mono/Assistance/Geometry.cs +++ b/mono/Assistance/Geometry.cs @@ -11,13 +11,13 @@ namespace Assistance { public static bool isEqual(double a, double b) { return Math.Abs(b - a) <= precision; } public static bool isLess(double a, double b) - { return b - a > precision; } + { return a - precision < b; } public static bool isGreater(double a, double b) - { return a - b > precision; } + { return b - precision < a; } public static bool isLessOrEqual(double a, double b) - { return a - b <= precision; } + { return a + precision <= b; } public static bool isGreaterOrEqual(double a, double b) - { return b - a <= precision; } + { return b + precision <= a; } public static double logNormalDistribuitionUnscaled(double x, double x0, double w) { return Math.Exp(-0.5*Math.Pow(Math.Log(x/x0)/w, 2.0))/x; @@ -76,7 +76,7 @@ namespace Assistance { } public static T linear(T p0, T p1, double l) - { return add(mul(sub(p1, p0), l), p0); } + { return add(mul(p0, 1.0-l), mul(p1, l)); } public static T spline(T p0, T p1, T t0, T t1, double l) { double ll = l*l; @@ -96,7 +96,7 @@ namespace Assistance { } public static double interpolationLinear(double p0, double p1, double l) - { return (p1 - p0)*l + p0; } + { return p0*(1.0 - l) + p1*l; } public static double interpolationSpline(double p0, double p1, double t0, double t1, double l) { double ll = l*l; diff --git a/mono/Assistance/InputManager.cs b/mono/Assistance/InputManager.cs index 11cfbdc..02ebce9 100644 --- a/mono/Assistance/InputManager.cs +++ b/mono/Assistance/InputManager.cs @@ -162,11 +162,18 @@ namespace Assistance { modifiers[i].modify(tracks[i], newKeyPoint, tracks[i+1]); } List subTracks = tracks[modifiers.Count]; - + // create handlers foreach(Track track in subTracks) if (track.handler == null) track.handler = new TrackHandler(this, track, keyPoints.Count); + + //Console.WriteLine("--- tracks:"); + //for(int i = 0; i < tracks.Count; ++i) { + // Console.WriteLine(" level " + i); + // foreach(Track t in tracks[i]) + // t.print(); + //} if (keyPoints.Count > 0) { // rollback diff --git a/mono/Assistance/InputModifierAssistants.cs b/mono/Assistance/InputModifierAssistants.cs index 915af47..3a98ba1 100644 --- a/mono/Assistance/InputModifierAssistants.cs +++ b/mono/Assistance/InputModifierAssistants.cs @@ -21,7 +21,7 @@ namespace Assistance { public List guidelines = new List(); public override Track.WayPoint calcWayPoint(double originalIndex) { - Track.WayPoint p = original.calcWayPoint(originalIndex); + Track.WayPoint p = base.calcWayPoint(originalIndex); return guidelines.Count > 0 ? guidelines[0].transformPoint(p) : p; } } diff --git a/mono/Assistance/InputModifierInterpolation.cs b/mono/Assistance/InputModifierInterpolation.cs index 4d896a0..b6af59b 100644 --- a/mono/Assistance/InputModifierInterpolation.cs +++ b/mono/Assistance/InputModifierInterpolation.cs @@ -38,16 +38,20 @@ namespace Assistance { if (start < 0) start = 0; int subStart = subTrack.floorIndex(subTrack.indexByOriginalIndex(start)); if (subStart < 0) subStart = 0; + if (subStart < subTrack.points.Count && subTrack.points[subStart].originalIndex + Geometry.precision < start) + ++subStart; + while(subStart > 0 && subTrack.points[subStart-1].originalIndex + Geometry.precision >= start) + --subStart; if (subStart < subTrack.points.Count) { subTrack.wayPointsRemoved += subTrack.points.Count - subStart; subTrack.points.RemoveRange(subStart, subTrack.points.Count - subStart); } // add points - Track.WayPoint p0 = track.getWayPoint(start - 1); + Track.WayPoint p0 = subTrack.modifier.calcWayPoint(start - 1); for(int i = start; i < track.points.Count; ++i) { - Track.WayPoint p1 = track.points[i]; + Track.WayPoint p1 = subTrack.modifier.calcWayPoint(i); addSegment(subTrack, p0, p1); p0 = p1; } diff --git a/mono/Assistance/InputModifierTangents.cs b/mono/Assistance/InputModifierTangents.cs index 6725912..82f30ae 100644 --- a/mono/Assistance/InputModifierTangents.cs +++ b/mono/Assistance/InputModifierTangents.cs @@ -18,7 +18,9 @@ namespace Assistance { Track.WayPoint p1 = original.getWayPoint(i1); p0.tangent = tangents[i0]; p1.tangent = tangents[i1]; - return Track.interpolate(p0, p1, frac); + Track.WayPoint p = Track.interpolate(p0, p1, frac); + p.originalIndex = originalIndex; + return p; } } diff --git a/mono/Assistance/ModifierSnowflake.cs b/mono/Assistance/ModifierSnowflake.cs index ea9b338..598da76 100644 --- a/mono/Assistance/ModifierSnowflake.cs +++ b/mono/Assistance/ModifierSnowflake.cs @@ -20,7 +20,7 @@ namespace Assistance { public List guidelines = new List(); public override Track.WayPoint calcWayPoint(double originalIndex) { - Track.WayPoint p = original.calcWayPoint(originalIndex); + Track.WayPoint p = base.calcWayPoint(originalIndex); Point pp = p.point.position - center; p.point.position = center + new Point(Point.dot(pp, px), Point.dot(pp, py)); p.tangent.position = new Point(Point.dot(p.tangent.position, px), Point.dot(p.tangent.position, py)); diff --git a/mono/Assistance/ModifierSpiro.cs b/mono/Assistance/ModifierSpiro.cs index aaec50d..f1d31ba 100644 --- a/mono/Assistance/ModifierSpiro.cs +++ b/mono/Assistance/ModifierSpiro.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace Assistance { public class ModifierSpiro: Modifier { - public static readonly double segmentSize = 0.25*Math.PI; + public static readonly double segmentSize = Math.PI/180.0*10.0; public class Handler: Track.Handler { public readonly List angles = new List(); @@ -18,22 +18,40 @@ namespace Assistance { public Modifier(Track.Handler handler, double angle, double radius): base(handler) { this.angle = angle; this.radius = radius; } public override Track.WayPoint calcWayPoint(double originalIndex) { - Track.WayPoint p = original.calcWayPoint(originalIndex); + Track.WayPoint p = base.calcWayPoint(originalIndex); Handler handler = (Handler)this.handler; - double frac; + double frac, a0, a1; + Point p0, p1; int i = original.floorIndex(originalIndex, out frac); - double angle = i < 0 ? 0 - : frac <= Geometry.precision ? handler.angles[i] - : handler.angles[i]*(1.0 - frac) + handler.angles[i + 1]*frac; - angle += this.angle; + if (frac > Geometry.precision) { + a0 = handler.angles[i]; + a1 = handler.angles[i+1]; + p0 = original.points[i].point.position; + p1 = original.points[i+1].point.position; + } else + if (i > 0) { + a0 = handler.angles[i-1]; + a1 = handler.angles[i]; + p0 = original.points[i-1].point.position; + p1 = original.points[i].point.position; + frac = 1.0; + } else { + a0 = handler.angles[i]; + a1 = handler.angles[i]; + p0 = original.points[i].point.position; + p1 = original.points[i].point.position; + } + + double angle = Geometry.interpolationLinear(a0, a1, frac) + this.angle; + double da = a1 - a0; double radius = 2.0*this.radius*p.point.pressure; double s = Math.Sin(angle); double c = Math.Cos(angle); p.point.position += new Point(c, s)*radius; - p.tangent.position = new Point(-s, c); + p.tangent.position = ((p1 - p0) + new Point(-s, c)*radius*(a1 - a0)).normalize(); return p; } } @@ -73,7 +91,8 @@ namespace Assistance { for(int i = start; i < track.points.Count; ++i) { if (i > 0) { double dl = track.points[i].length - track.points[i-1].length; - double da = 0.25*dl/(2.0*radius*track.points[i].point.pressure); + double da = track.points[i].point.pressure > Geometry.precision + ? 0.25*dl/(2.0*radius*track.points[i].point.pressure) : 0.0; handler.angles.Add(handler.angles[i-1] + da); } else { handler.angles.Add(0.0); @@ -83,8 +102,11 @@ namespace Assistance { // process sub-tracks foreach(Track subTrack in track.handler.tracks) { // remove points - int subStart = start;//subTrack.floorIndexNoClamp(subTrack.indexByOriginalIndex(start)); + int subStart = subTrack.floorIndex(subTrack.indexByOriginalIndex(start)); if (subStart < 0) subStart = 0; + if (subStart < subTrack.points.Count && subTrack.points[subStart].originalIndex + Geometry.precision < start) + ++subStart; + if (subStart < subTrack.points.Count) { subTrack.wayPointsRemoved += subTrack.points.Count - subStart; subTrack.points.RemoveRange(subStart, subTrack.points.Count - subStart); @@ -92,11 +114,11 @@ namespace Assistance { // add points for(int i = start; i < track.points.Count; ++i) { - if (false && i > 0) { + if (i > 0) { double prevAngle = handler.angles[i-1]; double nextAngle = handler.angles[i]; if (Math.Abs(nextAngle - prevAngle) > 1.5*segmentSize) { - double step = segmentSize/(nextAngle - prevAngle); + double step = segmentSize/Math.Abs(nextAngle - prevAngle); double end = 1.0 - 0.5*step; for(double frac = step; frac < end; frac += step) subTrack.points.Add( subTrack.modifier.calcWayPoint((double)i - 1.0 + frac) ); diff --git a/mono/Assistance/ToolFull.cs b/mono/Assistance/ToolFull.cs index d1872c7..391e9fb 100644 --- a/mono/Assistance/ToolFull.cs +++ b/mono/Assistance/ToolFull.cs @@ -33,6 +33,7 @@ namespace Assistance { if (r > Geometry.precision && r < 0.5) { color.a *= r/0.5; r = 0.5; } double rr = r + 1.0; + //rr += 10.0*(Math.Abs(point.tangent.position.x) + Math.Abs(point.tangent.position.y)) surface.expand(new Rectangle(p.x - rr, p.y - rr, p.x + rr, p.y + rr)); @@ -41,6 +42,15 @@ namespace Assistance { color.apply(surface.context); surface.context.Arc(p.x, p.y, r, 0.0, 2.0*Math.PI); surface.context.Fill(); + + //pen.apply(surface.context); + //color.a = 0.5; + //color.apply(surface.context); + //surface.context.LineWidth = 0.5; + //surface.context.MoveTo(p.x, p.y); + //surface.context.RelLineTo(-10.0*point.tangent.position.y, 10.0*point.tangent.position.x); + //surface.context.Stroke(); + surface.context.Restore(); } diff --git a/mono/Assistance/Track.cs b/mono/Assistance/Track.cs index ab9a104..75d81f7 100644 --- a/mono/Assistance/Track.cs +++ b/mono/Assistance/Track.cs @@ -26,8 +26,11 @@ namespace Assistance { { get { return handler.owner; } } public Track original { get { return handler.original; } } - public virtual WayPoint calcWayPoint(double originalIndex) - { return original.calcWayPoint(originalIndex); } + public virtual WayPoint calcWayPoint(double originalIndex) { + WayPoint p = original.calcWayPoint(originalIndex); + p.originalIndex = originalIndex; + return p; + } } public struct Point { @@ -258,6 +261,16 @@ namespace Assistance { Geometry.interpolationLinear(p0.length, p1.length, l), p1.depRootIndex ); } + + public void print() { + foreach(WayPoint wp in points) + Console.Write( + "{2:f1}, ", + wp.point.position.x, + wp.point.position.y, + wp.originalIndex ); + Console.WriteLine(); + } } }