常用的计算算法:
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);
}
}