Tilt倾斜率根据勾股定理a^2+b^2=c^2,等边直角三角形中为例,默认值最小值为2
接下来我们用一个正方体为例子做绘图.
Tilt为默认值2的时候如上图
Tilt值为10以上时候的效果
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace Common
{
/// <summary>
/// Creator:CHANHC
/// OpenCv 三维
/// </summary>
public class CV3D
{
static double[] AxisX = new double[] { };
static double[] AxisY = new double[] { };
static double[] AxisZ = new double[] { };
static List<double[][]> lineXYZ = new List<double[][]>();
//正方体原点到任意一边的距离(半边长)
static int MainPonitDistance = 300;
//倾斜比例(数值越高越接近平视,正常最小值为2)
public static double Tilt = 2;
/// <summary>
/// 输出图片
/// </summary>
public static void Show()
{
Mat img = new Mat(600, 600, MatType.CV_8UC3, new Scalar(255, 255, 255));
//Z轴 G
Cv2.Line(img, 300, 0, 300, 600, new Scalar(200, 255, 200), 1, LineTypes.AntiAlias);
#region Z轴箭头
Cv2.Line(img, 290, 20, 300, 0, new Scalar(200, 255, 200), 1, LineTypes.AntiAlias);
Cv2.Line(img, 300, 0, 310, 20, new Scalar(200, 255, 200), 1, LineTypes.AntiAlias);
#endregion
//X轴 R
Cv2.Line(img, 0, 300, 600, 300, new Scalar(200, 200, 255), 1, LineTypes.AntiAlias);
#region X轴箭头
Cv2.Line(img, 580, 290, 600, 300, new Scalar(200, 200, 255), 1, LineTypes.AntiAlias);
Cv2.Line(img, 580, 310, 600, 300, new Scalar(200, 200, 255), 1, LineTypes.AntiAlias);
#endregion
//Y轴 B
Cv2.Line(img, 88, 512, 512, 88, new Scalar(255, 200, 200), 1, LineTypes.AntiAlias);
#region Y轴箭头
Cv2.Line(img, 492, 98, 512, 88, new Scalar(255, 200, 200), 1, LineTypes.AntiAlias);
Cv2.Line(img, 502, 108, 512, 88, new Scalar(255, 200, 200), 1, LineTypes.AntiAlias);
#endregion
//测试正方体数据边长为100
Cv2.Line(img,OperX(0, 0), OperY(0, 0), OperX(100, 0), OperY(0, 0), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 0), OperY(0, 0), OperX(0, 0), OperY(100, 0), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 0), OperY(0, 0), OperX(0, 100), OperY(0, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 0), OperY(100, 0), OperX(100, 0), OperY(100, 0), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(100, 0), OperY(0, 0), OperX(100, 0), OperY(100, 0), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(100, 0), OperY(0, 0), OperX(100, 100), OperY(0, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 100), OperY(0, 100), OperX(100, 100), OperY(0, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 100), OperY(0, 100), OperX(0, 100), OperY(100, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(100, 100), OperY(0, 100), OperX(100,100), OperY(100, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 0), OperY(100, 0), OperX(0, 100), OperY(100, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(0, 100), OperY(100, 100), OperX(100, 100), OperY(100, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
Cv2.Line(img,OperX(100, 0), OperY(100, 0), OperX(100, 100), OperY(100, 100), new Scalar(0, 0, 0), 1, LineTypes.Link4);
//显示图像
Cv2.ImShow("3D", img);
//延时等待按键按下
Cv2.WaitKey(1);
Array.Clear(AxisX, 0, AxisX.Length);
Array.Clear(AxisY, 0, AxisY.Length);
Array.Clear(AxisZ, 0, AxisZ.Length);
lineXYZ.Clear();
}
/// <summary>
/// 关闭所有窗口
/// </summary>
public static void Hide() {
Cv2.DestroyAllWindows();
}
/// <summary>
/// 计算出对应二维的X坐标
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public static int OperX(double x, double y)
{
Tilt = Tilt < 2 ? 2 : Tilt;
int fx = 0;
fx = (int)x;
if (y!=0)
{
int yx = (int)(Sqrt(Pow(y) / Tilt));
fx += yx;
}
fx += MainPonitDistance;
return fx;
}
/// <summary>
/// 计算出对应二维的Y坐标
/// </summary>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns></returns>
public static int OperY(double z, double y)
{
Tilt = Tilt < 2 ? 2 : Tilt;
int fy = 0;
fy = (int)z;
if (y != 0)
{
int yz = (int)(Sqrt(Pow(y) / Tilt));
fy += yz;
}
fy = MainPonitDistance - fy;
return fy;
}
/// <summary>
/// 追加点
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void PutPoint(double[] x, double[] y, double[] z)
{
AxisX = AxisX.Concat(x).ToArray();
AxisY = AxisY.Concat(y).ToArray();
AxisZ = AxisZ.Concat(z).ToArray();
double[][] xyz = new double[][] { x, y, z };
lineXYZ.Add(xyz);
}
#region 数学函数
public static double Sin(double target) { return Math.Sin(target); }
public static double Cos(double target) { return Math.Cos(target); }
public static double Tan(double target) { return Math.Tan(target); }
public static double Atan(double target) { return Math.Atan(target); }
/// <summary>
/// 平方根
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public static double Sqrt(double target) { return Math.Sqrt(target); }
/// <summary>
/// 次幂 2=平方
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public static double Pow(double target) { return Math.Pow(target, 2); }
#endregion
}
}
调用测试
static void Main(){
while (true)
{
CV3D.Tilt += 0.1;
CV3D.Show();
Thread.Sleep(200);
CV3D.Hide();
}
Console.ReadKey();
}
后续按需要在测试正方体处改成自己要画的内容整合到AxisX、Y、Z里面,再把对应xyz传入oper对应函数(ps:建议把画图内容坐标轴最大值作为原点的单边一半,然后按比例再转换成单边一半的对应距离)