我正在编写一个可视化工具应用程序:它从XML加载构建几何体并在屏幕上绘制它。 建筑物由矩形房间组成,其中许多房间 - 所以我想在它们上面绘制它们的名字。
我使用this教程在我的表单中翻转Y轴,因为构建存储在笛卡尔坐标中的数据。并将所有这些转换为经典的Windows" y逐渐减少"系统虽然绘图看起来很奇怪。
我还需要扩展和翻译我的场景"到左下角。
而且,我最后的痛苦,我需要再次翻转我的文本 - 因为它也会翻转!
正如tutorial所说,我需要:
但是文字的坐标无效!
它们从正确的位置向下移动:(
所以这是我的问题 - 如何正确计算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);
}
答案 0 :(得分:1)
试试这个:
void DrawDigonalString(Graphics G, string S, Font F, Brush B, PointF P, int Angle)
{
SizeF MySize = G.MeasureString(S, F);
G.TranslateTransform(P.X + MySize.Width / 2, P.Y + MySize.Height / 2);
G.RotateTransform(Angle);
G.DrawString(S, F, B, new PointF(-MySize.Width / 2, -MySize.Height / 2));
G.RotateTransform(-Angle);
G.TranslateTransform(-P.X - MySize.Width / 2, -P.Y- MySize.Height / 2);
}
答案 1 :(得分:1)
最后我明白了! 下面的类在其中心绘制带有指定文本的矩形 - 在Y反转场景内 文本自动缩放以适合实际的矩形大小。享受:)
class RectangleWithText
{
RectangleF m_extent = new RectangleF();
string m_text = "";
Font m_textFont = null;
RectangleF m_textRect = new RectangleF();
public RectangleWithText( RectangleF extent, string text )
{
m_extent = extent;
m_text = text;
}
public void Draw( Graphics g )
{
var dashedGrayPen = new Pen( Color.Gray, 1.0f / g.DpiX ) { DashStyle = DashStyle.Dash };
var brownPen = new Pen( Color.Brown, 1.0f / g.DpiX );
// Draw rectangle itself
g.DrawRectangle( brownPen, m_extent.X, m_extent.Y, m_extent.Width, m_extent.Height );
// Draw text on it
var extentCenter = new PointF( ( m_extent.Left + m_extent.Right ) / 2, ( m_extent.Bottom + m_extent.Top ) / 2 );
DrawText( g, m_text, extentCenter, m_extent );
}
}
private void DrawText( Graphics g, string text, PointF ptStart, RectangleF extent )
{
var gs = g.Save();
// Inverse Y axis again - now it grow down;
// if we don't do this, text will be drawn inverted
g.ScaleTransform( 1.0f, -1.0f, MatrixOrder.Prepend );
if ( m_textFont == null )
{
// Find the maximum appropriate text size to fix the extent
float fontSize = 100.0f;
Font fnt;
SizeF textSize;
do
{
fnt = new Font( "Arial", fontSize / g.DpiX, FontStyle.Bold, GraphicsUnit.Pixel );
textSize = g.MeasureString( text, fnt );
m_textRect = new RectangleF( new PointF( ptStart.X - textSize.Width / 2.0f, -ptStart.Y - textSize.Height / 2.0f ), textSize );
var textRectInv = new RectangleF( m_textRect.X, -m_textRect.Y, m_textRect.Width, m_textRect.Height );
if ( extent.Contains( textRectInv ) )
break;
fontSize -= 1.0f;
if ( fontSize <= 0 )
{
fontSize = 1.0f;
break;
}
} while ( true );
m_textFont = fnt;
}
// Create a StringFormat object with the each line of text, and the block of text centered on the page
var stringFormat = new StringFormat()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
g.DrawString( text, m_textFont, Brushes.Black, m_textRect, stringFormat );
g.Restore( gs );
}
}