Skip to content

Commit

Permalink
完成
Browse files Browse the repository at this point in the history
  • Loading branch information
jim-kirisame committed Jul 11, 2017
1 parent 1861056 commit 1dacebe
Show file tree
Hide file tree
Showing 12 changed files with 4,718 additions and 6 deletions.
104 changes: 104 additions & 0 deletions LinkedListExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
namespace System.Collections.Generic
{
/// <summary>
/// Provides extension methods for LinkedList.
/// </summary>
public static class LinkedListExtensions
{
/// <summary>
/// Finds the next node after the given node that contains the specified value.
/// </summary>
/// <typeparam name="T">The type of value in the linked list.</typeparam>
/// <param name="list">The linked list.</param>
/// <param name="node">The node after which to search for the value in the linked list, or <c>null</c> to search from the beginning.</param>
/// <param name="value">The value to locate in the linked list.</param>
/// <returns>The first node after the given node that contains the specified value, if found; otherwise, <c>null</c>.</returns>
public static LinkedListNode<T> FindNext<T>(this LinkedList<T> list, LinkedListNode<T> node, T value)
{
if (list == null)
{
throw new ArgumentNullException("list");
}

if (node == null)
{
return list.Find(value);
}

if (list != node.List)
{
throw new ArgumentException("The list does not contain the given node.");
}

EqualityComparer<T> comparer = EqualityComparer<T>.Default;

// Skip the given node.
node = node.Next;
while (node != null)
{
if (value != null)
{
if (comparer.Equals(node.Value, value))
{
return node;
}
}
else if (node.Value == null)
{
return node;
}
node = node.Next;
}

return null;
}

/// <summary>
/// Finds the previous node before the given node that contains the specified value.
/// </summary>
/// <typeparam name="T">The type of value in the linked list.</typeparam>
/// <param name="list">The linked list.</param>
/// <param name="node">The node before which to search for the value in the linked list, or <c>null</c> to search from the end.</param>
/// <param name="value">The value to locate in the linked list.</param>
/// <returns>The first node before the given node that contains the specified value, if found; otherwise, <c>null</c>.</returns>
public static LinkedListNode<T> FindPrevious<T>(this LinkedList<T> list, LinkedListNode<T> node, T value)
{
if (list == null)
{
throw new ArgumentNullException("list");
}

if (node == null)
{
return list.FindLast(value);
}

if (list != node.List)
{
throw new ArgumentException("The list does not contain the given node.");
}

EqualityComparer<T> comparer = EqualityComparer<T>.Default;

// Skip the given node.
node = node.Previous;
while (node != null)
{
if (value != null)
{
if (comparer.Equals(node.Value, value))
{
return node;
}
}
else if (node.Value == null)
{
return node;
}
node = node.Previous;
}

return null;
}
}
}
17 changes: 14 additions & 3 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
<Window x:Class="PixelCircle.MainWindow"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PixelCircle"
xmlns:Controls="clr-namespace:System.Windows.Controls" x:Class="PixelCircle.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
Title="PixelCircle" Height="380" Width="680">
<Grid>

<DockPanel Name="DockPanel1">
<StackPanel Width="100px" Margin="10,10,0,10" Panel.ZIndex="99">
<Label Content="Dimension: " Margin="5,0,5,0"/>
<TextBox x:Name="tb1" Height="23" TextWrapping="Wrap" Text="15" Margin="5,0,5,0"/>
<CheckBox x:Name="checkbox1" Content="Show Grid" Margin="5,5,5,5"/>
<Button Content="Draw" Height="23" Click="Button_Click" Margin="5,5,5,5"/>
</StackPanel>
<Controls:ZoomableCanvas x:Name="Canvas1" Margin="10,10,10,10" Background="AliceBlue" MouseWheel="Canvas1_MouseWheel" MouseDown="Canvas1_MouseDown" MouseMove="Canvas1_MouseMove" MouseUp="Canvas1_MouseUp" MouseLeave="Canvas1_MouseLeave">
</Controls:ZoomableCanvas>
</DockPanel>

</Grid>
</Window>
229 changes: 229 additions & 0 deletions MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,238 @@ namespace PixelCircle
/// </summary>
public partial class MainWindow : Window
{
bool Pan = false;
Point Origin, MouseOrigin;
public MainWindow()
{
InitializeComponent();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
int size = int.Parse(tb1.Text);
DrawCircle(size - 1, (bool)checkbox1.IsChecked);
}

private void DrawCircle(int size, bool axis)
{
var points = CalcCirclePoint(size);

if (Canvas1.ActualHeight < 5 * size + 10)
{
Canvas1.Height = 5 * size + 10;
Canvas1.UpdateLayout();
}
if (Canvas1.ActualWidth < 5 * size + 10)
{
Canvas1.Width = 5 * size + 10;
Canvas1.UpdateLayout();
}

int offX = (int)Canvas1.ActualWidth / 2;
int offY = (int)Canvas1.ActualHeight / 2;

Canvas1.Children.Clear();

if (axis)
DrawAxis(offX, offY, 0, (int)Canvas1.ActualWidth, 0, (int)Canvas1.ActualHeight, 5);

DrawPoints(points, 5, offX, offY);
Canvas1.Offset = new Point(0, 0);
}

private void DrawAxis(int centerX, int centerY, int X1, int X2, int Y1, int Y2, int size)
{
Line temp;
for (int i = 0; i * size * 5 + centerX < X2; i++)
{
temp = new Line()
{
Y1 = Y1,
Y2 = Y2,
X1 = i * size * 5 + centerX,
X2 = i * size * 5 + centerX,
Name = "Yp" + i.ToString(),
Stroke = i % 2 == 0 ? Brushes.Black : Brushes.DarkRed,
StrokeThickness = 1,
ToolTip = i * 5
};
Canvas1.Children.Add(temp);
}
for (int i = 0; i * size * 5 + centerX > X1; i--)
{
temp = new Line()
{
Y1 = Y1,
Y2 = Y2,
X1 = i * size * 5 + centerX,
X2 = i * size * 5 + centerX,
Name = "Yn" + i.Abs().ToString(),
Stroke = i % 2 == 0 ? Brushes.Black : Brushes.DarkRed,
StrokeThickness = 1,
ToolTip = i * 5
};
Canvas1.Children.Add(temp);
}
for (int i = 0; i * size * 5 + centerY > Y1; i--)
{
temp = new Line()
{
Y1 = i * size * 5 + centerY,
Y2 = i * size * 5 + centerY,
X1 = X1,
X2 = X2,
Name = "Xn" + i.Abs().ToString(),
Stroke = i % 2 == 0 ? Brushes.Black : Brushes.DarkRed,
StrokeThickness = 1,
ToolTip = -i * 5
};
Canvas1.Children.Add(temp);
}
for (int i = 0; i * size * 5 + centerY < Y2; i++)
{
temp = new Line()
{
Y1 = i * size * 5 + centerY,
Y2 = i * size * 5 + centerY,
X1 = X1,
X2 = X2,
Name = "Xp" + i.ToString(),
Stroke = i % 2 == 0 ? Brushes.Black : Brushes.DarkRed,
StrokeThickness = 1,
ToolTip = -i * 5
};
Canvas1.Children.Add(temp);
}
}

private void DrawPoints(List<Vector> points, uint size, double offX, double offY)
{
for (int i = 0; i < points.Count; i++)
{
var rect = NewRect(points[i].X, points[i].Y, size, "P" + i.ToString(), (int)offX, (int)offY);
Canvas1.Children.Add(rect);
}
}

Rectangle NewRect(double x, double y, uint size, string name, int offsetX, int offsetY)
{
Rectangle rec = new Rectangle()
{
Margin = new Thickness(x * size + offsetX - size / 2, y * size + offsetY - size / 2, 0, 0),
Width = size,
Height = size,
Fill = Brushes.DarkGray,
Name = name,
Stroke = Brushes.DimGray,
StrokeThickness = 1,
ToolTip = "(" + x.Round().ToString() + ", " + (-y.Round()).ToString() + ")",
};
return rec;
}


List<Vector> CalcCirclePoint(int d)
{
double r = d / 2.0d;
bool type = d % 2 == 0;

List<Vector> points = new List<Vector>();

double x = r, y = type ? 0 : 0.5;
points.Add(new Vector(x, y));

while (x > y)
{
y += 1;
var d1 = getDiff(x, y, r);
var d2 = getDiff(x - 1, y, r);
x = d1 <= d2 ? x : x - 1;

points.Add(new Vector(x, y));
}
return ExtendCirclePoint(points);
}

List<Vector> ExtendCirclePoint(List<Vector> orig)
{
List<Vector> ext = new List<Vector>();
foreach (var item in orig)
{
ext.Add(item);

Vector sp = new Vector(item.Y, item.X);
if (!sp.Equals(item)) ext.Add(sp);
}

orig = ext;

ext = new List<Vector>();
foreach (var item in orig)
{
ext.Add(item);

Vector sp = new Vector(-item.X, item.Y);
if (!sp.Equals(item)) ext.Add(sp);
}
orig = ext;

ext = new List<Vector>();
foreach (var item in orig)
{
ext.Add(item);

Vector sp = new Vector(item.X, -item.Y);
if (!sp.Equals(item)) ext.Add(sp);
}
return ext;
}

double getDiff(double x, double y, double R)
{
return Math.Abs(x * x + y * y - R * R);
}

private void Canvas1_MouseWheel(object sender, MouseWheelEventArgs e)
{
var o = Canvas1.Offset;
var m = e.GetPosition(Canvas1);
var p = new Vector(m.X, m.Y);

Canvas1.Scale *= e.Delta > 0 ? 1.25d : 0.8d;

p *= e.Delta > 0 ? 0.2d : -0.25d; //画布点移动距离
p *= Canvas1.Scale; //实际窗口点移动距离

Canvas1.Offset = o + p;
}

private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
Pan = true;

MouseOrigin = e.GetPosition(DockPanel1);
Origin = Canvas1.Offset;
var CanvasOrigin = e.GetPosition(Canvas1);
}

private void Canvas1_MouseMove(object sender, MouseEventArgs e)
{
if (Pan)
{
var b = e.GetPosition(DockPanel1);
Canvas1.Offset = new Point(Origin.X - b.X + MouseOrigin.X, Origin.Y - b.Y + MouseOrigin.Y);
}
}

private void Canvas1_MouseLeave(object sender, MouseEventArgs e)
{
Pan = false;
}

private void Canvas1_MouseUp(object sender, MouseButtonEventArgs e)
{
Pan = false;
}
}
}
Loading

0 comments on commit 1dacebe

Please sign in to comment.