C# 反向Y轴上的图形文本
我正在编写一个可视化应用程序:它从XML加载构建几何体并在屏幕上绘制。 这座建筑由长方形的房间组成,其中很多房间——所以我想在上面画上它们的名字 我使用教程在表单中翻转Y轴,因为建筑数据存储在笛卡尔坐标中。并将它们全部转换为经典的Windows“y向下生长”系统,而绘图看起来很奇怪。C# 反向Y轴上的图形文本,c#,.net,winforms,drawing,gdi+,C#,.net,Winforms,Drawing,Gdi+,我正在编写一个可视化应用程序:它从XML加载构建几何体并在屏幕上绘制。 这座建筑由长方形的房间组成,其中很多房间——所以我想在上面画上它们的名字 我使用教程在表单中翻转Y轴,因为建筑数据存储在笛卡尔坐标中。并将它们全部转换为经典的Windows“y向下生长”系统,而绘图看起来很奇怪。 我还需要缩放并将“场景”转换到左下角。 而且,我最后的痛苦是,我需要再次翻转我的文本——因为它也会翻转 正如我所说,我需要: 翻转Y轴,缩放场景并将其移动到所需位置 在笛卡尔坐标系中绘制建筑几何图形(仅矩形) 返回
我还需要缩放并将“场景”转换到左下角。
而且,我最后的痛苦是,我需要再次翻转我的文本——因为它也会翻转 正如我所说,我需要:
它们从正确的位置向下移动:(
这就是我的问题-如何正确计算Windows窗体对象中的新文本坐标 试试这个:
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);
}
终于找到了!下面的类在其中心-内部Y反转的场景中绘制具有指定文本的矩形。
文本自动缩放以适合实际矩形大小。请欣赏:)
使用文本对矩形进行分类
{
矩形F m_区段=新矩形F();
字符串m_text=“”;
Font m_textFont=null;
矩形F m_textRect=新矩形F();
公共矩形带文本(矩形范围、字符串文本)
{
m_范围=范围;
m_text=文本;
}
公共空间绘制(图g)
{
var dashedGrayPen=新笔(Color.Gray,1.0f/g.DpiX){DashStyle=DashStyle.Dash};
var brownPen=新笔(颜色为棕色,1.0f/g.DpiX);
//绘制矩形本身
g、 DrawRectangle(棕色、m_extent.X、m_extent.Y、m_extent.Width、m_extent.Height);
//在上面画文字
var extentCenter=新的点f((m_extent.Left+m_extent.Right)/2,(m_extent.Bottom+m_extent.Top)/2);
DrawText(g、m_文本、extentCenter、m_范围);
}
}
私有void DrawText(图形g、字符串文本、PointF ptStart、矩形范围)
{
var gs=g.Save();
//再次反转Y轴-现在它向下生长;
//如果我们不这样做,文本将被绘制为反向
g、 标度转换(1.0f,-1.0f,矩阵顺序前置);
如果(m_textFont==null)
{
//查找适当的最大文本大小以修复范围
浮动字体大小=100.0f;
字体fnt;
SizeF textSize;
做
{
fnt=新字体(“Arial”,fontSize/g.DpiX,FontStyle.Bold,GraphicsUnit.Pixel);
textSize=g.MeasureString(text,fnt);
m_textRect=新矩形F(新点F(ptStart.X-textSize.Width/2.0f,-ptStart.Y-textSize.Height/2.0f),textSize);
var textRectInv=新矩形f(m_textrct.X,-m_textrct.Y,m_textrct.Width,m_textrct.Height);
if(区段包含(textRectInv))
打破
fontSize-=1.0f;
如果(fontSize和agjusted translation(g.TranslateTransform(50,高度-100,MatrixOrder.Append)
您的函数工作得很好,谢谢。我这样称呼它:DrawDigonalString(g,“ID:+box.ID,fnt,brush.Black,new PointF(box.X1,-box.Y1),0)
.P.S.你能简单解释一下它是如何工作的吗?我只发现了一个问题:文本和矩形的缩放方式不同。也就是说,使用较小的缩放值,文本从其父矩形“向外突出”
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);
}
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 );
}
}