Files
HandyControl/Net35/HandyControl_Net35/Tools/Helper/ArithmeticHelper.cs
T
2019-01-21 00:43:10 +08:00

152 lines
5.9 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media.Media3D;
namespace HandyControl.Tools
{
/// <summary>
/// 包含内部使用的一些简单算法
/// </summary>
internal class ArithmeticHelper
{
/// <summary>
/// 平分一个整数到一个数组中
/// </summary>
/// <param name="num"></param>
/// <param name="count"></param>
/// <returns></returns>
public static int[] DivideInt2Arr(int num, int count)
{
var arr = new int[count];
var div = num / count;
var rest = num % count;
for (int i = 0; i < count; i++)
{
arr[i] = div;
}
for (int i = 0; i < rest; i++)
{
arr[i] += 1;
}
return arr;
}
/// <summary>
/// 计算控件在窗口中的可见坐标
/// </summary>
public static Point CalSafePoint(FrameworkElement element, FrameworkElement showElement, Thickness thickness = default(Thickness))
{
if (element == null || showElement == null) return default(Point);
var point = element.PointToScreen(new Point(0, 0));
if (point.X < 0) point.X = 0;
if (point.Y < 0) point.Y = 0;
var maxLeft = SystemParameters.WorkArea.Width -
((double.IsNaN(showElement.Width) ? showElement.ActualWidth : showElement.Width) +
thickness.Left + thickness.Right);
var maxTop = SystemParameters.WorkArea.Height -
((double.IsNaN(showElement.Height) ? showElement.ActualHeight : showElement.Height) +
thickness.Top + thickness.Bottom);
return new Point(maxLeft > point.X ? point.X : maxLeft, maxTop > point.Y ? point.Y : maxTop);
}
/// <summary>
/// 获取布局范围框
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public static Rect GetLayoutRect(FrameworkElement element)
{
var num1 = element.ActualWidth;
var num2 = element.ActualHeight;
if (element is Image || element is MediaElement)
if (element.Parent is Canvas)
{
num1 = double.IsNaN(element.Width) ? num1 : element.Width;
num2 = double.IsNaN(element.Height) ? num2 : element.Height;
}
else
{
num1 = element.RenderSize.Width;
num2 = element.RenderSize.Height;
}
var width = element.Visibility == Visibility.Collapsed ? 0.0 : num1;
var height = element.Visibility == Visibility.Collapsed ? 0.0 : num2;
var margin = element.Margin;
var layoutSlot = LayoutInformation.GetLayoutSlot(element);
var x = 0.0;
var y = 0.0;
switch (element.HorizontalAlignment)
{
case HorizontalAlignment.Left:
x = layoutSlot.Left + margin.Left;
break;
case HorizontalAlignment.Center:
x = (layoutSlot.Left + margin.Left + layoutSlot.Right - margin.Right) / 2.0 - width / 2.0;
break;
case HorizontalAlignment.Right:
x = layoutSlot.Right - margin.Right - width;
break;
case HorizontalAlignment.Stretch:
x = Math.Max(layoutSlot.Left + margin.Left,
(layoutSlot.Left + margin.Left + layoutSlot.Right - margin.Right) / 2.0 - width / 2.0);
break;
}
switch (element.VerticalAlignment)
{
case VerticalAlignment.Top:
y = layoutSlot.Top + margin.Top;
break;
case VerticalAlignment.Center:
y = (layoutSlot.Top + margin.Top + layoutSlot.Bottom - margin.Bottom) / 2.0 - height / 2.0;
break;
case VerticalAlignment.Bottom:
y = layoutSlot.Bottom - margin.Bottom - height;
break;
case VerticalAlignment.Stretch:
y = Math.Max(layoutSlot.Top + margin.Top,
(layoutSlot.Top + margin.Top + layoutSlot.Bottom - margin.Bottom) / 2.0 - height / 2.0);
break;
}
return new Rect(x, y, width, height);
}
/// <summary>
/// 计算两点的连线和x轴的夹角
/// </summary>
/// <param name="center"></param>
/// <param name="p"></param>
/// <returns></returns>
public static double CalAngle(Point center, Point p) => Math.Atan2(p.Y - center.Y, p.X - center.X) * 180 / Math.PI;
/// <summary>
/// 判断是否是有效的双精度浮点数
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsValidDoubleValue(object value)
{
var d = (double)value;
if (!double.IsNaN(d))
return !double.IsInfinity(d);
return false;
}
/// <summary>
/// 计算法线
/// </summary>
/// <param name="p0"></param>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
public static Vector3D CalNormal(Point3D p0, Point3D p1, Point3D p2)
{
var v0 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
var v1 = new Vector3D(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
return Vector3D.CrossProduct(v0, v1);
}
}
}