using System; using System.Collections.Generic; namespace Assistance { public class ModifierSnowflake: Modifier { public class Modifier: Track.Modifier { Point center, px, py; public Modifier(Track.Handler handler, Point center, double angle, bool flip): base(handler) { this.center = center; double s = Math.Sin(angle); double c = Math.Cos(angle); if (flip) { px = new Point(c, s); py = new Point(s,-c); } else { px = new Point(c,-s); py = new Point(s, c); } } public InputManager.KeyPoint.Holder holder = null; public List guidelines = new List(); public override Track.Point calcPoint(double originalIndex) { Track.Point p = base.calcPoint(originalIndex); Point pp = p.position - center; p.position = center + new Point(Point.dot(pp, px), Point.dot(pp, py)); return p; } } public ActivePoint center; public int rays; public ModifierSnowflake(Document document, Point center, int rays = 6): base(document) { this.center = new ActivePoint(this, ActivePoint.Type.CircleCross, center); this.rays = rays; } public override void draw(Cairo.Context context) { for(int i = 0; i < rays/2; ++i) { Point pp0 = center.position; Point pp1 = center.position + new Point(100.0, 0.0).rotate( i*2.0*Math.PI/(double)rays ); Rectangle bounds = Drawing.Helper.getBounds(context); Geometry.truncateInfiniteLine(bounds, ref pp0, ref pp1); context.Save(); pen.apply(context); context.MoveTo(pp0.x, pp0.y); context.LineTo(pp1.x, pp1.y); context.Stroke(); context.Restore(); } } public override void modify(Track track, InputManager.KeyPoint keyPoint, List outTracks) { if (track.handler == null) { track.handler = new Track.Handler(this, track); for(int i = 0; i < rays; ++i) { double angle = i*2.0*Math.PI/(double)rays; track.handler.tracks.Add(new Track( new Modifier(track.handler, center.position, angle, false) )); track.handler.tracks.Add(new Track( new Modifier(track.handler, center.position, angle, true) )); } } outTracks.AddRange(track.handler.tracks); if (!track.isChanged) return; int start = track.points.Count - track.wayPointsAdded; if (start < 0) start = 0; foreach(Track subTrack in track.handler.tracks) { // remove points if (start < subTrack.points.Count) { subTrack.wayPointsRemoved += subTrack.points.Count - start; subTrack.points.RemoveRange(start, subTrack.points.Count - start); } // add points for(int i = start; i < track.points.Count; ++i) subTrack.points.Add( subTrack.modifier.calcPoint(i) ); subTrack.wayPointsAdded += subTrack.points.Count - start; } track.wayPointsRemoved = 0; track.wayPointsAdded = 0; } } }