C#当中,图形位置计算相关(两点位置,两线夹角计算,矩形和圆交互等)

这篇文章详细介绍了几种常见的计算算法,如线与圆的交点坐标计算、两点间距离和角度测量,以及点在矩形和圆中的判断,还包括根据点旋转文本和图片的图形处理方法,主要涉及.NET中的MapDrawTool类实现。
摘要由CSDN通过智能技术生成

常用的计算算法:
1.计算一条线和圆相交的两点的坐标
2.计算2点距离
3.计算2点之间的角度
4.计算点是否在矩形中
5.判断矩形是否在圆中
6.判断点是否在圆中
7.绘制根据点旋转文本,一般旋转点给定位文本包围盒中心点

public class MapDrawTool
{
    /// <summary>
    /// 计算一条线和圆相交的两点的坐标
    /// </summary>
    /// <param name="x1"></param>
    /// <param name="y1"></param>
    /// <param name="x2"></param>
    /// <param name="y2"></param>
    /// <param name="cx"></param>
    /// <param name="cy"></param>
    /// <param name="r"></param>
    /// <returns></returns>
    public static PointF[]? FindLineCircleIntersection(double x1, double y1, double x2, double y2, double cx, double cy, double r)
    {
        var dx = x2 - x1;
        var dy = y2 - y1;

        var A = dx * dx + dy * dy;
        var B = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
        var C = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy) - r * r;

        var discriminant = B * B - 4 * A * C;

        if (discriminant < 0)
        {
            return null;
        }
        else if (discriminant == 0)
        {
            return null;
        }
        else
        {
            var t1 = (-B + Math.Sqrt(discriminant)) / (2 * A);
            var t2 = (-B - Math.Sqrt(discriminant)) / (2 * A);
            var intersectionX1 = x1 + t1 * dx;
            var intersectionY1 = y1 + t1 * dy;
            var intersectionX2 = x1 + t2 * dx;
            var intersectionY2 = y1 + t2 * dy;
            var points = new PointF[2];
            points[0] = new PointF((float)intersectionX1, (float)intersectionY1);
            points[1] = new PointF((float)intersectionX2, (float)intersectionY2);
            return points;
        }
    }

    /// <summary>
    /// 计算2点距离
    /// </summary>
    /// <param name="point1"></param>
    /// <param name="point2"></param>
    /// <returns></returns>
    public static double CalculateDistance(System.Windows.Point point1, System.Windows.Point point2)
    {
        var deltaX = point2.X - point1.X;
        var deltaY = point2.Y - point1.Y;

        // 使用勾股定理计算距离
        var distance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);

        return distance;
    }

    /// <summary>
    /// 计算2点之间的角度
    /// </summary>
    /// <param name="startPoint"></param>
    /// <param name="endPoint"></param>
    /// <returns></returns>
    public static double CalculateAngle(PointF startPoint, PointF endPoint)
    {
        double deltaX = endPoint.X - startPoint.X;
        double deltaY = endPoint.Y - startPoint.Y;

        // 使用反正切函数计算角度(以弧度表示)
        var angleInRadians = Math.Atan2(deltaY, deltaX);

        // 将弧度转换为度数
        var angleInDegrees = angleInRadians * (180.0 / Math.PI);

        // 确保角度在0到360度之间
        if (angleInDegrees > 0)
        {
            angleInDegrees -= 360;
        }

        return angleInDegrees;
    }

    /// <summary>
    /// 计算点是否在矩形中
    /// </summary>
    /// <param name="rect"></param>
    /// <param name="point"></param>
    /// <returns></returns>
    public static bool IsPointInsideRect(System.Drawing.RectangleF rect, System.Drawing.PointF point)
    {
        if (point.X >= rect.Left
            && point.X <= rect.Right
            && point.Y >= rect.Top
            && point.Y <= rect.Bottom)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static System.Drawing.Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
    {
        System.Drawing.Bitmap bitmap;
        using (var stream = new MemoryStream())
        {
            BitmapEncoder encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
            encoder.Save(stream);
            bitmap = new System.Drawing.Bitmap(stream);
        }

        return bitmap;
    }

    public static System.Drawing.Bitmap GetBitmapSourceToBitmap(BitmapSource bitmapSource)
    {
        System.Drawing.Bitmap bitmap;
        using (var stream = new System.IO.MemoryStream())
        {
            var encoder = new BmpBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
            encoder.Save(stream);
            bitmap = new System.Drawing.Bitmap(stream);
        }

        return bitmap;
    }

    public static BitmapImage GetBitmapSourceToBitmapImage(BitmapSource bitmapSource)
    {
        var bitmapImage = new BitmapImage();

        using (var memoryStream = new MemoryStream())
        {
            var encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
            encoder.Save(memoryStream);

            memoryStream.Seek(0, SeekOrigin.Begin);

            bitmapImage.BeginInit();
            bitmapImage.StreamSource = memoryStream;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.EndInit();
        }

        return bitmapImage;
    }

    /// <summary>
    /// 转换成指定bitmap=>BitmapImage绑定
    /// </summary>
    /// <param name="bitmap"></param>
    /// <returns></returns>
    public static BitmapImage GetBitmapImageBybitmap(System.Drawing.Bitmap bitmap)
    {
        var bitmapImage = new BitmapImage();
        try
        {
            using (var ms = new MemoryStream())
            {
                bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = ms;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                bitmapImage.Freeze();
            }
        }
        catch
        {
        }

        return bitmapImage;
    }

    /// <summary>
    /// 判断矩形是否在圆中
    /// </summary>
    /// <param name="rectangle"></param>
    /// <param name="center"></param>
    /// <param name="radius"></param>
    /// <returns></returns>
    public static bool IsRectangleInsideCircle(System.Drawing.RectangleF rectangle, PointF center, double radius)
    {
        var topLeft = new PointF(rectangle.Left, rectangle.Top);
        var topRight = new PointF(rectangle.Right, rectangle.Top);
        var bottomLeft = new PointF(rectangle.Left, rectangle.Bottom);
        var bottomRight = new PointF(rectangle.Right, rectangle.Bottom);

        return IsPointInsideCircle(topLeft, center, radius)
            && IsPointInsideCircle(topRight, center, radius)
            && IsPointInsideCircle(bottomLeft, center, radius)
            && IsPointInsideCircle(bottomRight, center, radius);
    }

    /// <summary>
    /// 判断矩形是否在圆中
    /// </summary>
    /// <param name="rectangle"></param>
    /// <param name="center"></param>
    /// <param name="radius"></param>
    /// <returns></returns>
    public static bool IsHasRectangleInsideCircle(System.Drawing.RectangleF rectangle, PointF center, double radius)
    {
        var topLeft = new PointF(rectangle.Left, rectangle.Top);
        var topRight = new PointF(rectangle.Right, rectangle.Top);
        var bottomLeft = new PointF(rectangle.Left, rectangle.Bottom);
        var bottomRight = new PointF(rectangle.Right, rectangle.Bottom);

        // Check if all four points of the rectangle are inside the circle
        return IsPointInsideCircle(topLeft, center, radius)
            || IsPointInsideCircle(topRight, center, radius)
            || IsPointInsideCircle(bottomLeft, center, radius)
            || IsPointInsideCircle(bottomRight, center, radius);
    }

    /// <summary>
    /// 判断点是否在圆中
    /// </summary>
    /// <param name="point"></param>
    /// <param name="center"></param>
    /// <param name="radius"></param>
    /// <returns></returns>
    public static bool IsPointInsideCircle(PointF point, PointF center, double radius)
    {
        var distance = Math.Sqrt(Math.Pow(point.X - center.X, 2) + Math.Pow(point.Y - center.Y, 2));
        return distance <= radius;
    }

    /// <summary>  
    /// 绘制根据点旋转文本,一般旋转点给定位文本包围盒中心点  
    /// </summary>  
    /// <param name="s">文本</param>  
    /// <param name="font">字体</param>  
    /// <param name="brush">填充</param>  
    /// <param name="point">旋转点</param>  
    /// <param name="format">布局方式</param>  
    /// <param name="angle">角度</param>  
    public static void DrawString(System.Drawing.Graphics graphics, string s, System.Drawing.Font font, System.Drawing.Brush brush, System.Drawing.PointF point, System.Drawing.StringFormat format, float angle)
    {
        // Save the matrix  
        var mtxSave = graphics.Transform;

        var mtxRotate = graphics.Transform;
        mtxRotate.RotateAt(angle, point);
        graphics.Transform = mtxRotate;

        graphics.DrawString(s, font, brush, point, format);

        // Reset the matrix  
        graphics.Transform = mtxSave;
    }

    /// <summary>
    /// 旋转图片
    /// </summary>
    /// <param name="graphics"></param>
    /// <param name="angle">角度</param>
    public static void RotateBitmap(System.Drawing.Graphics graphics, float angle, int CenterX, int CenterY)
    {
        // 设置旋转中心
        graphics.TranslateTransform(CenterX, CenterY);
        // 旋转图像
        graphics.RotateTransform(angle);
        // 恢复旋转中心
        graphics.TranslateTransform(-CenterX, -CenterY);
    }
}
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖的诗人Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值