C# 反向Y轴上的图形文本

C# 反向Y轴上的图形文本,c#,.net,winforms,drawing,gdi+,C#,.net,Winforms,Drawing,Gdi+,我正在编写一个可视化应用程序:它从XML加载构建几何体并在屏幕上绘制。 这座建筑由长方形的房间组成,其中很多房间——所以我想在上面画上它们的名字 我使用教程在表单中翻转Y轴,因为建筑数据存储在笛卡尔坐标中。并将它们全部转换为经典的Windows“y向下生长”系统,而绘图看起来很奇怪。 我还需要缩放并将“场景”转换到左下角。 而且,我最后的痛苦是,我需要再次翻转我的文本——因为它也会翻转 正如我所说,我需要: 翻转Y轴,缩放场景并将其移动到所需位置 在笛卡尔坐标系中绘制建筑几何图形(仅矩形) 返回

我正在编写一个可视化应用程序:它从XML加载构建几何体并在屏幕上绘制。 这座建筑由长方形的房间组成,其中很多房间——所以我想在上面画上它们的名字

我使用教程在表单中翻转Y轴,因为建筑数据存储在笛卡尔坐标中。并将它们全部转换为经典的Windows“y向下生长”系统,而绘图看起来很奇怪。
我还需要缩放并将“场景”转换到左下角。
而且,我最后的痛苦是,我需要再次翻转我的文本——因为它也会翻转

正如我所说,我需要:

  • 翻转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 );
        }
    }