You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SharpDX Direct2D绘制负坐标位图时RawRectangleF截断问题求解

问题分析与解决办法

你的问题核心在于创建BitmapRenderTarget时只覆盖了正坐标区域,负坐标的DXF对象根本没被渲染到位图里,所以后续DrawBitmap时负区域自然没有内容。

具体问题点

在LoadBitmap方法中,你创建BitmapRenderTarget用的是new Size2F((float)Extents.Right, (float)Extents.Bottom),这相当于只创建了从(0,0)到(Right,Bottom)的画布,所有负坐标的对象都在这个画布之外,根本没被绘制。

解决步骤

  1. 计算完整的画布范围:要包含所有正负坐标的对象,画布宽度应该是Extents.Right - Extents.Left,高度是Extents.Bottom - Extents.Top(因为Extents.Left可能为负,这样宽度才是实际总跨度)。
  2. 渲染DXF对象时做坐标平移:把所有对象的坐标加上偏移量(-Extents.Left, -Extents.Top),这样原来的负坐标会被移到位图的正区域内,确保所有内容都能被绘制到位图里。
  3. 渲染位图时匹配视图坐标:根据当前的视图平移需求,计算位图对应区域的位置,绘制到目标RenderTarget上。

修改后的代码示例

1. 调整LoadBitmap方法

private void LoadBitmap(RenderTarget target)
{
    if (LayerManager is null)
    {
        return;
    }
    if (bitmapRenderTarget is not null)
    {
        bitmapRenderTarget.Dispose();
        bitmapRenderTarget = null;
    }

    // 计算完整的画布尺寸:包含正负坐标的总跨度
    float canvasWidth = (float)(Extents.Right - Extents.Left);
    float canvasHeight = (float)(Extents.Bottom - Extents.Top);
    // 创建覆盖所有区域的BitmapRenderTarget
    bitmapRenderTarget = new BitmapRenderTarget(target, CompatibleRenderTargetOptions.None, new Size2F(canvasWidth, canvasHeight));
    
    bitmapRenderTarget.BeginDraw();
    bitmapRenderTarget.Clear(new RawColor4(1.0f, 1.0f, 0f, 1.0f));

    // 计算坐标偏移量,把所有对象移到位图的正区域内
    float offsetX = (float)-Extents.Left;
    float offsetY = (float)-Extents.Top;

    foreach (var layer in LayerManager.Layers.Values)
    {
        if (layer.IsVisible)
        {
            foreach (var o in layer.DrawingObjects)
            {
                if (o is DrawingLine drawingLine)
                {
                    drawingLine.UpdateBrush(drawingLine.DxfLine, bitmapRenderTarget);
                    // 这里需要修改DrawLine逻辑,支持传入偏移量处理坐标平移
                    DxfHelpers.DrawLineWithOffset(drawingLine, bitmapRenderTarget.Factory, bitmapRenderTarget, currentThickness, offsetX, offsetY);
                }
            }
        }
    }
    bitmapRenderTarget.EndDraw();
    bitmapRenderTargetNeedsUpdate = false;
    bitmapLoaded = true;
}

2. 调整RenderBitmap方法

private void RenderBitmap(RenderTarget target)
{
    if (bitmapRenderTarget is not null)
    {
        if (bitmapRenderTargetNeedsUpdate)
        {
            LoadBitmap(target);
        }

        // 假设当前视图平移量为viewOffsetX、viewOffsetY
        float viewOffsetX = -200;
        float viewOffsetY = -200;
        // 位图源矩形:对应视图区域在已平移位图中的位置
        RawRectangleF sourceRect = new(
            (float)(-viewOffsetX - Extents.Left),
            (float)(-viewOffsetY - Extents.Top),
            (float)(500 - Extents.Left),
            (float)(1000 - Extents.Top)
        );
        // 目标矩形:RenderTarget上的显示位置
        RawRectangleF destRect = new(-200, -200, 500, 1000);

        target.DrawBitmap(bitmapRenderTarget.Bitmap, destRect, 1.0f, BitmapInterpolationMode.Linear, sourceRect);
    }
}

额外优化建议

  • 不需要每次修改视图都重新生成位图:可以通过设置RenderTarget.Transform实现平移缩放,仅在DXF内容变化时更新位图,提升大文件处理性能。
  • 若缩放频繁,可根据当前缩放级别生成对应分辨率的位图,或直接用RenderTarget的Transform结合局部重绘,避免频繁生成大位图。

内容的提问来源于stack exchange,提问作者user25472896

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:02:44