/// <summary> /// Cycles through a list of points and creates a fractal /// version of the points by splitting each one in half and /// moving it a random amount. /// </summary> /// <returns>A true if at least one point was changed.</returns> public static bool StaggerPoints( CenterPointList points, MersenneRandom random, float minimumDistance) { // Ignores blanks and null if (points == null) throw new ArgumentException("points cannot be null"); if (random == null) throw new ArgumentException("random cannot be null"); if (points.Count < 2) return false; // Go through each set of points CenterPointList newPoints = new CenterPointList(); bool changed = false; for (int i = 0; i < points.Count - 1; i++) { // Get the points CenterPoint p1 = points[i]; CenterPoint p2 = points[i + 1]; // Add the first point newPoints.Add(p1); // Get the distance float distance = CalculateDistance(p1.Point, p2.Point); if (distance > minimumDistance) { // These two are far enough to calculate a new point CenterPoint mp = new CenterPoint((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2); float delta = distance * Constants.FractalDecay; float diff = random.NextSingle(-delta, delta); // Calculate the new point float dy = p2.Y - p1.Y; float dx = p2.X - p1.X; if (dy == 0) { // This is a horizontal line mp.Y += diff; } else if (dx == 0) { // This is a vertical line mp.X += diff; } else { // Figure out the slope of the line double theta1 = Math.Tanh(dy / dx); double theta2 = theta1 - Math.PI / 2; mp.X = (float) (mp.X + diff * Math.Cos(theta2)); mp.Y = (float) (mp.Y + diff * Math.Sin(theta2)); } // Add the created point newPoints.Add(mp); changed = true; } // Add the second point newPoints.Add(p2); } // See if we changes something if (changed) { // Swap the points points.Clear(); points.AddAll(newPoints); newPoints.Clear(); } // Return our status return changed; }
/// <summary> /// Gets the distance between two points. /// </summary> public float GetDistance(CenterPoint point) { return Geometry.CalculateDistance(Point, point.Point); }
/// <summary> /// Draws a little widget in the center to indicate the center of /// the segment point. /// </summary> private void RenderSegmentHandle(Context g, CenterPoint segmentPoint) { // Set up the variables PointF p = new PointF(cx + segmentPoint.X, cy + segmentPoint.Y); double s2 = (handleSize / 4) / scale; // Draw a red circle g.Color = new Color(0, 0, 0.75f); g.Arc(p.X, p.Y, s2, 0, Math.PI * 2); g.Fill(); }