C#画三维坐标系

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:建议把画图内容坐标轴最大值作为原点的单边一半,然后按比例再转换成单边一半的对应距离)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值