我正在编写一个可视化应用程序:它从XML中加载建筑物的几何形状,并将其绘制在屏幕上。建筑物由矩形房间组成,其中许多-所以我想在上面绘制他们的名字。
我使用this教程翻转Y轴在我的形式,因为建筑数据存储在笛卡尔坐标。并将它们转换为经典的Windows“y向下生长”系统,而绘图看起来很奇怪。
我还需要缩放和翻译我的“场景”到左下角。
而且,我最后的痛苦,我需要再次翻转我的文字-因为它也会翻转!
正如tutorial所说,我需要:
1.翻转Y轴,缩放并将场景移动到所需位置
1.在笛卡尔坐标系中绘制建筑物几何图形(只是矩形)
1.回到“Y向下生长”的系统,规模再移动
1.在这个“经典”系统中绘制文本
但文本的坐标无效!
从正确的位置向下移动:(
所以这是我的问题-如何计算新的文本坐标在Windows窗体对象 * 正确 *。
void VisualizerForm_Paint(object sender, PaintEventArgs e)
{
// Setup graphics output settings
var g = e.Graphics;
g.Clear(Color.White);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.PageUnit = GraphicsUnit.Pixel;
// Move coordinate system center to the bottom left corner,
// scale it to user-defined scale value and flip Y axis (mul it scale to -1)
g.ScaleTransform(m_scale, -m_scale, MatrixOrder.Append);
g.TranslateTransform(50, Height - 50, MatrixOrder.Append);
// ... Draw some complex building geometry ...
// Draw building room
var customPen = new Pen(Color.Black, 1.0f / g.DpiX);
var rect = new RectangleF(box.X1, box.Y1, (box.X2 - box.X1), (box.Y2 - box.Y1));
g.DrawRectangle(customPen, box.X1, box.Y1, (box.X2 - box.X1), (box.Y2 - box.Y1));
GraphicsState gs = g.Save();
// First reset transform matrix
g.ResetTransform();
// Then again scale and move scene, but now with classic down-incresed Y axis
g.ScaleTransform(m_scale, m_scale, MatrixOrder.Append);
g.TranslateTransform(50, Height - 50, MatrixOrder.Append);
// All Y coords now must be inverted :/ *sigh*
box.Y1 *= -1.0f;
box.Y2 *= -1.0f;
rect = new RectangleF(box.X1, box.Y1, Math.Abs(box.X2 - box.X1), Math.Abs(box.Y2 - box.Y1));
// FIXME: This text is drawing in incorrect place
var fnt = new Font("Arial", 40f / g.DpiX, FontStyle.Bold, GraphicsUnit.Pixel);
g.DrawString("ID: " + box.Id, fnt, Brushes.Black, rect, stringFormat);
g.Restore(gs);
}
3条答案
按热度按时间qqrboqgw1#
试试这个:
1aaf6o9v2#
终于拿到了!
下面的类在其中心内Y反转的场景中绘制具有指定文本的矩形。
文本自动缩放以适应实际矩形大小。
sy5wg1nm3#
我最近遇到了这个线程时,我想做完全相同的事情作为操作。这是令人沮丧的尝试和拼凑一切在一起,特别是因为上面的例子,其中划分字体大小的DPI有点人为,特别是在较新的屏幕上具有较高的DPI。
因此,我创建了自己的示例,并粘贴在下面。('ResizeEnd'处理程序不是真的必要的,但它是一种通过稍微调整Form 1窗口大小来重新运行程序的方便方法)。然后用下面的代码替换Paint和resize处理程序的内容,并复制粘贴两个辅助函数的ConvertRectangleToPointFArray()'和'TextInsideRectangle()'添加到项目中。如所编写的,示例程序将在窗体底部附近绘制一个坐标系,并正确标记“X”和“Y”轴(这要求在绘制'Y'字符串之前将其反转。如果'verbose' bool变量设置为'true',一些诊断信息将被写入输出窗口。2请享用!