首页 > 其他分享 >转动指针,转动拨盘

转动指针,转动拨盘

时间:2023-09-11 16:23:23浏览次数:30  
标签:拨盘 angle int currentScale 转动 pictureBox1 centerX centerY 指针

初始效果图(左), 转动指针效果图(中),转动拨盘效果图(右)

  

 代码如下:

        int centerX = 124;
        int centerY = 124;
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = GetPointerImg(Resources.valsalvaThresholdPointer, 90f, pictureBox1.Width, pictureBox1.Height, centerX, centerY);
            pictureBox1.Image = bmp;
            lb_currentScale.Text = currentScale.ToString();
        }

        bool mouseMoved = false;
        int currentScale = 5;//当前刻度,取值范围[0,5]
        int moveStartX = int.MinValue;
        int moveStartY = int.MinValue;
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            moveStartX = e.X;
            moveStartY = e.Y;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            mouseMoved = true;
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (!mouseMoved || (moveStartX == int.MinValue && moveStartY == int.MinValue)) return;//拖动才绘制

            mouseMoved = false;
            Console.WriteLine($"X:{e.X}-{moveStartX},Y:{e.Y}-{moveStartY}");

            //计算刻度步进
            int addition = 1;
            //以变化大的为准
            if (Math.Abs(e.Y - moveStartY) > Math.Abs(e.X - moveStartX)) addition = e.X.CompareTo(centerX) * moveStartY.CompareTo(e.Y);//中心点右方,↑为正,左方↓为正
            else addition = e.Y.CompareTo(centerY) * e.X.CompareTo(moveStartX);//中心点上方,←为正,下方→为正

            float currentAngle = (5 - currentScale) * 18;//当前角度,每个刻度 90/5 度
            Console.WriteLine($"currentAngle:{currentAngle},addition:{addition}");
            currentScale += addition;
            if (currentScale > 5 || currentScale < 0)
            {
                currentScale -= addition;
            }
            else if (addition != 0)
            {
                //1.5秒内过渡到下一个刻度
                Task.Run(() =>
                {                                       
                    //帧率24,1.5秒共36帧,每帧 1000/24 毫秒
                    for (int i = 0; i < 36; i++)
                    {
                        currentAngle -= addition * 0.5f;//角度变化和刻度相反,每帧 18/36 度
                        var bmp = GetPieImg(Resources.valsalvaThresholdPie, currentAngle, centerX, centerY);
                        pictureBox1.BackgroundImage = bmp;
                        Thread.Sleep(42);
                    }
                });

                lb_currentScale.Text = currentScale.ToString();
            }

            moveStartX = int.MinValue;
            moveStartY = int.MinValue;
        }

        private Bitmap GetPieImg(Bitmap pieImg, float angle, int centerX, int centerY)
        {
            // 创建新的位图作为旋转后的图片
            Bitmap rotatedImage = new Bitmap(pieImg.Width, pieImg.Height);

            // 创建一个Graphics对象,用于绘制旋转后的图片
            using (Graphics g = Graphics.FromImage(rotatedImage))
            {
                // 设置旋转中心点为图片中心
                g.TranslateTransform(centerX, centerY);

                // 执行旋转
                g.RotateTransform(angle);

                // 恢复旋转中心点到原位置
                g.TranslateTransform(-centerX, -centerY);

                g.DrawImage(pieImg, Point.Empty);
            }
            return rotatedImage;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if (moveStartX != int.MinValue) return;
            var ea = (MouseEventArgs)e;
            double distance = Math.Sqrt(Math.Pow(ea.X - centerX, 2) + Math.Pow(ea.Y - centerY, 2));//点击处到圆心的距离
            double angle = Math.Asin((centerY - ea.Y) / distance) * 180 / Math.PI;
            if (centerX < ea.X && centerY > ea.Y) angle = 180- angle;//第一象限
            else if (centerX > ea.X && centerY < ea.Y) angle = 0;//第三象限
            else if (centerX < ea.X && centerY < ea.Y) angle = 180;//第四象限
            text_Angle.Text = angle.ToString("f3");
            var bmp = GetPointerImg(Resources.valsalvaThresholdPointer, (float)angle, pictureBox1.Width, pictureBox1.Height, centerX, centerY);
            pictureBox1.Image = bmp;
        }

        private void btn_DrawPointer_Click(object sender, EventArgs e)
        {
            var angle = Convert.ToDouble(text_Angle.Text);
            var bmp = GetPointerImg(Resources.valsalvaThresholdPointer, (float)angle, pictureBox1.Width, pictureBox1.Height, centerX, centerY);
            pictureBox1.Image = bmp;
        }

        private Bitmap GetPointerImg(Bitmap pointerImg, float angle, int w, int h, int centerX, int centerY)
        {
            // 创建新的位图作为旋转后的图片
            Bitmap rotatedImage = new Bitmap(w, h);

            // 创建一个Graphics对象,用于绘制旋转后的图片
            using (Graphics g = Graphics.FromImage(rotatedImage))
            {
                g.FillEllipse(new SolidBrush(Color.Red), new Rectangle(centerX - 5, centerY - 5, 10, 10));

                // 设置旋转中心点为图片中心
                g.TranslateTransform(centerX, centerY);

                // 执行旋转
                g.RotateTransform(angle);

                // 恢复旋转中心点到原位置
                g.TranslateTransform(-centerX, -centerY);

                g.DrawImage(pointerImg, 0, centerY - pointerImg.Height / 2);
            }
            return rotatedImage;
        }

 

标签:拨盘,angle,int,currentScale,转动,pictureBox1,centerX,centerY,指针
From: https://www.cnblogs.com/chixiner/p/17693822.html

相关文章

  • BUG1-野指针问题
    问题 像是第27行,对指针声明却未赋初值,就会成为野指针。会导致意料之外的结果。这里我遇到的是程序卡死,当按下KEY_UP时,程序就会卡死。      解决赋个值,让wTemp指向Num1的地址 ......
  • 18、复合类型之指针(P47、P48、P49、P50);C++ primer 2.3.2
    1、C++中的“声明符”是什么?声明符是用来指定变量或函数的类型、名称和属性的符号。例如:intlist[20]; 声明了一个名为list的整型数组,它有20个元素。int是类型说明符,list[20]是声明符char*cp; 声明了一个名为cp的指向字符的指针1。*cp是声明符doublefunc(void);......
  • Go 中普通指针、unsafe.Pointer 与 uintptr 之间的关系和指针运算
    C语言指针运算指针运算就是对指针类型的变量做常规数学运算,例如加减操作,实现地址的偏移。指针运算在C语言中是原生支持的,可以直接在指针变量上做加减,例如:#include<stdio.h>constintMAX=3;intmain(){intvar[]={10,100,200};inti,*ptr;/*......
  • 空指针产生的条件 null对象调用属性
    null对象调用属性 e.gpublicclassStudent{Integerage;Stringname;Stringaddress;Useruser;}Studentstudent=newStudent();12:student.getUser().getName()Exceptioninthread"main"java.lang.NullPointerException atpatter......
  • 画圆盘的指针
    效果图 privateBitmapGetPointerImg(BitmappointerImg,floatangle,intw,inth,intcenterX,intcenterY){//创建新的位图作为旋转后的图片BitmaprotatedImage=newBitmap(w,h);//创建一个Graphics......
  • 通过指针变量存取一维数组元素
    通过指针变量存取一维数组元素下面展示一下。#include<stdio.h>intmain(){ inta[10],*p; for(p=a;p<a+10;p++) { scanf("%d",p); }for(p=a;p<a+10;p++) { printf("%d",*p); } printf("\n"); return0;}测试输入......
  • 单词搜索 II(字典树、数组)、合并两个有序数组(数组、双指针)、验证回文串(双指针、字
    单词搜索II(字典树、数组)给定一个mxn二维字符网格board****和一个单词(字符串)列表words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一......
  • 学习使用双指针(leetcode)
    一、K和数对的最大数目(JAVA)给你一个整数数组nums和一个整数k。每一步操作中,你需要从数组中选出和为k的两个整数,并将它们移出数组。返回你可以对数组执行的最大操作数。示例1:输入:nums=[1,2,3,4],k=5输出:2解释:开始时nums=[1,2,3,4]:-移出1和4,......
  • 双指针法删除数组里面的值
    你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 说明:为什么返回数......
  • 代码随想录刷题记录——双指针篇
    27.移除元素题目链接快慢指针,最终返回index值为移除元素后的数组末尾元素下标+1.#include<vector>usingnamespacestd;classSolution{public:intremoveElement(vector<int>&nums,intval){//快慢指针intnums_length=nums.size();......