在OpenGL中,我可以这样做:
glOrtho(-10, 10, -10, 10, -1, 1)
建立一个坐标系,其中x的范围是-10到10,y的范围是-10到10.
有没有办法在WPF中更改画布的坐标系?
答案 0 :(得分:10)
我在Canvas上创建了一个扩展方法,允许您设置笛卡尔坐标系。示例调用是:
canvas.SetCoordinateSystem(-10, 10, -10, 10)
这将设置canvas
的坐标系,使x从-10到10,y从-10到10。
这是扩展方法:
public static Canvas SetCoordinateSystem(this Canvas canvas, Double xMin, Double xMax, Double yMin, Double yMax)
{
var width = xMax - xMin;
var height = yMax - yMin;
var translateX = -xMin;
var translateY = height + yMin;
var group = new TransformGroup();
group.Children.Add(new TranslateTransform(translateX, -translateY));
group.Children.Add(new ScaleTransform(canvas.ActualWidth / width, canvas.ActualHeight / -height));
canvas.RenderTransform = group;
return canvas;
}
这是一个演示程序,它在画布上绘制Sin(x)以及X和Y轴:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace CanvasScale
{
public static class CanvasUtils
{
public static Canvas SetCoordinateSystem(this Canvas canvas, Double xMin, Double xMax, Double yMin, Double yMax)
{
var width = xMax - xMin;
var height = yMax - yMin;
var translateX = -xMin;
var translateY = height + yMin;
var group = new TransformGroup();
group.Children.Add(new TranslateTransform(translateX, -translateY));
group.Children.Add(new ScaleTransform(canvas.ActualWidth / width, canvas.ActualHeight / -height));
canvas.RenderTransform = group;
return canvas;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
SizeChanged += (s, e) => canvas.SetCoordinateSystem(-10, 10, -10, 10);
canvas.Children.Add(new Line() { X1 = -10, Y1 = 0, X2 = 10, Y2 = 0, Stroke = Brushes.Black, StrokeThickness = 0.2 });
canvas.Children.Add(new Line() { X1 = 0, Y1 = -10, X2 = 0, Y2 = 10, Stroke = Brushes.Black, StrokeThickness = 0.2 });
var polyline = new Polyline()
{
Stroke = Brushes.BurlyWood,
StrokeThickness = 0.1,
Points = new PointCollection()
};
for (var x = -10.0; x <= 10.0; x += 0.1)
polyline.Points.Add(new Point(x, Math.Sin(x)));
canvas.Children.Add(polyline);
}
}
}
这就是它的样子:
答案 1 :(得分:1)
OrthographicCamera
提供正交投影,而不是更常见的透视投影(PerspectiveCamera
)。
要确定从相机可见的坐标“范围”,您可能需要摆弄Width
和Position
属性。
答案 2 :(得分:1)
只要您不设置Canvas.Top
,Canvas.Left
,Canvas.Right
或Canvas.Bottom
属性,就可以设置LayoutTransform或{{3 “画布”中每个子项的属性为适当的TransformGroup或RenderTransform:
Rect viewport = new Rect(-10, -10, 20, 20);
double scaleX = ActualWidth / viewport.Width;
double scaleY = ActualHeight / viewport.Height;
RenderTransform = new MatrixTransform(
scaleX, 0d, 0d, scaleY, -viewport.X * scaleX, -viewport.Y * scaleY);