WPF 坐标投影
程序员文章站
2022-05-27 16:46:24
...
WPF 坐标投影
有些时候,我们需要自己来制作一个画板,并在画板上绘制我们想要的内容(画图、状态图、统计图等)。此次给大家介绍一下自制画板。
建立画板
建立一个画板,并在画板中建立一个绘图区域TragetsCanvas,并用10X10px的小方格进行分割,添加刻度画板ScaleCanvas,刻度画板与绘图区域之间存在一些间隔,这些间隔用于填充坐标等分割信息。
<Canvas Width="1300" Height="2600" Background="#FF0E3151">
<Border Width="1" Canvas.Top="0" Canvas.Left="650" Background="#5500B6FB" Height="2600"/>
<Canvas x:Name="ScaleCanvas" Width="1300" Height="2600">
</Canvas>
<Canvas Width="1000" Height="2500" Canvas.Left="150" Canvas.Top="10" ClipToBounds="True">
<Rectangle Width="1000" Height="2500">
<Rectangle.Fill>
<DrawingBrush Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile" Opacity="1">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#20A0BAB0">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0 10,1" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#20A0BAB0">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0 1,10" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
<Canvas Width="1000" Height="2500" x:Name="TragetsCanvas">
</Canvas>
</Canvas>
</Canvas>
坐标系转换
我们实际的坐标与设备的坐标一般情况下是不同的,设备默认坐标系的原点(0,0)在左上角,横轴(X)向右为正方向,竖轴(Y)向下为正方向。
/// <summary>
/// 坐标系
/// </summary>
public class CoordinateTranslation
{
// 整个宽度 px
double hallUiWidth = 1000;
// 整个高度 px
double hallUiHeight = 2500;
double actualMinW = -50;
double actualMaxW = 50;
double actualMaxH = 250;
double actualMinH = 0;
/// <summary>
/// True水平坐标从左到右-50~50 False反之50~-50
/// </summary>
public bool IsSmallToLargeLtoR { get; set; } = false;
public double TranslateToUiX(double x)
{
double result = 0;
// 判断当前坐标X在宽度上的比例
double rate = hallUiWidth / (actualMaxW - actualMinW);
if (IsSmallToLargeLtoR)
{
result = ((x - actualMinW) * rate);
}
else
{
result = (hallUiWidth - ((x - actualMinW) * rate));
}
return CenterTranslateX(result);
}
public double TranslateToUiY(double y)
{
double result = 0;
// 判断当前坐标Y在高度度上的比例
double rate = hallUiHeight / (actualMaxH - actualMinH);
result = hallUiHeight - ((y - actualMinH) * rate);
return CenterTranslateY(result);
}
// 目标的整体宽度
double targetWidth = 50;
// 目标的整体高度
double targetHeight = 100;
/// <summary>
/// 目标的方块显示高度
/// </summary>
public double CubeHeight { get; set; } = 40;
/// <summary>
///
/// </summary>
/// <param name="x">目标在坐标轴上的坐标X(目标的左上角坐标X)</param>
/// <returns></returns>
private double CenterTranslateX(double x)
{
double result = 0;
result = x - targetWidth / 2.0;
return result;
}
private double CenterTranslateY(double y)
{
double result = 0;
result = y - (targetHeight / 2.0 + CubeHeight / 2.0);
return result;
}
}
坐标系和我们刻度信息是息息相关的。
添加刻度信息
在构造函数中添加刻度信息,函数如下所示:
/// <summary>
/// 初始化刻度
/// </summary>
private void InitScale()
{
// y轴上偏移
double yOffset = 10;
// x轴上偏移
double xOffset = 150;
// 整个宽度 px
double hallWidth = 1000;
// 整个高度 px
double hallHeight = 2500;
// 大刻度间隔 px
double rate = 100;
// 水平刻度最小
double hScale = -50;
// 垂直刻度最小
double vScale = 0;
// 水平坐标从左到右-50~50 反之50~-50
bool isHorizontalSmallToLarge = true;
if (isHorizontalSmallToLarge)
{
for (int i = 0; i <= 10; i++)
{
TextBlock text = new TextBlock();
text.Foreground = Brushes.Gray;
string tt = (hScale + i * 10).ToString();
text.Text = tt;
ScaleCanvas.Children.Add(text);
double s = ((tt.Length * text.FontSize) / 4.0);
double x = i * rate + xOffset;
Canvas.SetLeft(text, x - s);
Canvas.SetTop(text, hallHeight + yOffset + 10);
Line line = new Line() { Stroke = new SolidColorBrush(Color.FromArgb(99, 0, 0xB6, 0xFB)), StrokeThickness = 1 };
if (i == 5)
{
line.X1 = x;
line.X2 = x;
line.Y1 = 0;
line.Y2 = 2600;
}
else
{
line.X1 = x;
line.X2 = x;
line.Y1 = yOffset;
line.Y2 = yOffset + hallHeight;
}
ScaleCanvas.Children.Add(line);
}
}
else
{
for (int i = 0; i <= 10; i++)
{
TextBlock text = new TextBlock();
text.Foreground = Brushes.Gray;
string tt = ((-hScale) - i * 10).ToString();
text.Text = tt;
ScaleCanvas.Children.Add(text);
double s = ((tt.Length * text.FontSize) / 4.0);
double x = i * rate + xOffset;
Canvas.SetLeft(text, x - s);
Canvas.SetTop(text, hallHeight + yOffset + 10);
Line line = new Line() { Stroke = new SolidColorBrush(Color.FromArgb(99, 0, 0xB6, 0xFB)), StrokeThickness = 1 };
if (i == 5)
{
line.X1 = x;
line.X2 = x;
line.Y1 = 0;
line.Y2 = 2600;
}
else
{
line.X1 = x;
line.X2 = x;
line.Y1 = yOffset;
line.Y2 = yOffset + hallHeight;
}
ScaleCanvas.Children.Add(line);
}
}
for (int i = 0; i <= 25; i++)
{
TextBlock text = new TextBlock() { TextAlignment = TextAlignment.Right, Width = 90 };
text.Foreground = Brushes.Gray;
string tt = (vScale + i * 10).ToString();
text.Text = tt;
ScaleCanvas.Children.Add(text);
double s = ((text.FontSize) / 4.0);
double y = 2500 - (i * rate - yOffset);
Canvas.SetLeft(text, 50);
Canvas.SetTop(text, y - s);
// 右边刻度
TextBlock text2 = new TextBlock() { TextAlignment = TextAlignment.Left, Width = 90 };
text2.Foreground = Brushes.Gray;
text2.Text = tt;
ScaleCanvas.Children.Add(text2);
Canvas.SetLeft(text2, hallWidth + xOffset + 10);
Canvas.SetTop(text2, y - s);
Line line = new Line() { Stroke = new SolidColorBrush(Color.FromArgb(99, 0, 0xB6, 0xFB)), StrokeThickness = 1 };
// 第一条占满
if (i == 0)
{
line.X1 = 0;
line.X2 = 1300;
line.Y1 = y;
line.Y2 = y;
}
else
{
line.X1 = xOffset;
line.X2 = xOffset + hallWidth;
line.Y1 = y;
line.Y2 = y;
}
ScaleCanvas.Children.Add(line);
}
}
效果
积跬步以至千里:) (:一阵没来由的风
上一篇: Cows POJ - 2481
下一篇: kafka单机版安装