工信部网站域名备案,广州微网站制作,网站开发者 敬请期待,高陵微网站建设目录
三、关键帧编辑
1、新建Winform工程
#xff08;1#xff09;界面布局 #xff08;2#xff09;全局变量
2、关键帧添加和删除
#xff08;1#xff09;鼠标在曲线上识别
#xff08;2#xff09;键盘按键按下捕捉
#xff08;3#xff09;关键帧添加、删…目录
三、关键帧编辑
1、新建Winform工程
1界面布局 2全局变量
2、关键帧添加和删除
1鼠标在曲线上识别
2键盘按键按下捕捉
3关键帧添加、删除 4修改关键帧值
3、曲线插值
1三次样条插值
2工程代码下载链接
四、曲线数据导出和读取
1、数据导出 1添加导出按钮
2工程代码下载链接
2、读取导出的数据
1手动按钮创建曲线 2读取导出得关键帧数据 3工程代码下载链接
五、全部工程下载
1、基本功能
2、核心功能 接上一节《C#时间轴曲线图形编辑器开发1-基本功能》继续。
C#时间轴曲线图形编辑器开发1-基本功能_Big_潘大师的博客-CSDN博客
三、关键帧编辑
1、新建Winform工程
重新创建新的Winform工程测试
1界面布局 2全局变量 KeyDatasClass _keyData new KeyDatasClass();SplineEdit cureDraw;float tensionSpline1 0.5f; //曲线1粗细//曲线编辑Dictionaryint, float keyListDatas new Dictionaryint, float(); //关键帧集合Color editSplineColor Color.Blue; //曲线颜色bool isMouseOnKeyPoint false; //鼠标是否在关键点上检测int dataLength 0;float[] myEditDatas; //绘制的曲线数据 int[] KeyDatasflag; //当前曲线数据是否是关键帧数据标值位float[] keyEditDatas_X; //关键帧-方框点绘制-X轴数据float[] keyEditDatas_Y; //关键帧-方框点绘制-X轴数据bool isDataEdit false; //关键帧是否要编辑bool isKeyEditDataMoveCan false;int keyEditFrame 0; //当前要编辑的关键帧数据//鼠标当前在画图面板上的像素坐标对应的坐标轴数值bool isMouseOnSpline; //鼠标在曲线上检测int currentValue_X;float currentValue_Y;int last_CurrentValueX 0;int ex 0, ey 0; //鼠标的坐标值bool isLeftButtonDowm false, isMiddleButtonDown false, isRightButtonDown false;bool isCtrlKeyDown false;bool isShiftDown false;
2、关键帧添加和删除
当检测鼠标在曲线上的时候通过键盘和鼠标的组合按键操作可以进行关键帧添加和删除操作。 1鼠标在曲线上识别
重新整理曲线识别代码将其代码封装。将封装好的代码放在timer1_Tick中执行 /// summary/// 检测鼠标是否在绘制得曲线上/// /summaryprivate void MouseOnSplineCheck(){//if (currentValue_X dataLength){int nIndex currentValue_X;if (nIndex myEditDatas.Length){nIndex myEditDatas.Length - 1;if (nIndex 0){nIndex 0;}}float selectValue_Y myEditDatas[nIndex];if (Math.Abs(selectValue_Y - currentValue_Y) cureDraw.YSliceValue / 8){isMouseOnSpline true;labMousePos.ForeColor editSplineColor;}else{isMouseOnSpline false;labMousePos.ForeColor Color.Black;}}else{labMousePos.ForeColor Color.Black;}}
2键盘按键按下捕捉
①在窗口属性中找到KeyPreview设置为True ②在窗口事件程序中分别添加KeyDowm、KeyUp事件函数 MainForm_KeyDown() private void MainForm_KeyDown(object sender, KeyEventArgs e){Keys k e.KeyCode;if (k Keys.ControlKey){isCtrlKeyDown true;}if (k Keys.ShiftKey){isShiftDown true;}}
MainForm_KeyUp() private void MainForm_KeyUp(object sender, KeyEventArgs e){Keys k e.KeyCode;if (k Keys.ControlKey){isCtrlKeyDown false;}if (k Keys.ShiftKey){isShiftDown false;}}
3关键帧添加、删除
①关键帧添加
鼠标在曲线上的时候Ctrl键鼠标左键按下添加关键帧
②关键帧删除
鼠标在曲线上的时候Shift键鼠标左键按下删除当前关键帧
③添加pictureBox1控件的单击事件函数pictureBox1_Click private void pictureBox1_Click(object sender, EventArgs e){//添加关键帧数据if(isMouseOnSpline isCtrlKeyDown){if (currentValue_X dataLength){MessageBox.Show(数据超过极限范围);return;}//判断关键帧是否可以添加判断当前要添加的关键帧是否已经存在bool isKeyListCanAdd false;for (int i 0; i keyEditDatas_X.Length; i){if(currentValue_X!keyEditDatas_X[i]){isKeyListCanAdd true;}}for (int i 0; i keyEditDatas_X.Length; i){if (currentValue_X keyEditDatas_X[i]){isKeyListCanAdd false;}}if (isKeyListCanAdd){//keyListDatas.Add(currentValue_X, currentValue_Y); //关键帧值设置为当前位置值keyListDatas.Add(currentValue_X, 0.0f); //关键帧值设置为0} }//删除当前关键帧if (isKeyEditDataMoveCan isShiftDown){keyListDatas.Remove(keyEditFrame); //删除关键帧数据myEditDatas[keyEditFrame] 0.0f; //将曲线数据值修改为0}} 4修改关键帧值 修改关键帧值除了鼠标拖动外还要需要可以手动输入操作这样可以精确的给定关键帧值。 实现方法鼠标在关键帧的时候右键双击弹出输入对话框。
①新建窗口 打开该窗口读取当前关键帧值、点击确定或者按回车将输入的值传到关键帧上。
窗口需要设置键盘识别 添加键盘事件KeyDataSetForm_KeyDown
判断Enter键按下 private void KeyDataSetForm_KeyDown(object sender, KeyEventArgs e){Keys k e.KeyCode;if (k Keys.Enter){_Son.KeyDataSet float.Parse(txtKeyDataSet.Text);this.Close();}if (k Keys.Escape){this.Close();}} 使用构造函数的方法进行窗口传值。操作方法见工程代码
②pictureBox1控件添加双击事件pictureBox1_DoubleClick private void pictureBox1_DoubleClick(object sender, EventArgs e){if (isRightButtonDown (label7.BackColor Color.Lime)){//MessageBox.Show(123);KeyDataSetForm kdf new KeyDataSetForm(this, _keyData);_keyData.KeyDataSet currentValue_Y;kdf.ShowDialog();keyListDatas[keyEditFrame] _keyData.KeyDataSet;}}
3、曲线插值 插值的目的是根据当前关键帧的值得到一条完整的连续、圆滑曲线。这时就需要用到插值法来计算曲线数组每个元素的值。
1三次样条插值
插值代码见程序工程。方法是首先要将关键帧数据进行排序然后再插值计算。
修改KeyDataTrans()代码添加三次样条插值 /// summary/// 关键帧数据集合转数组/// /summaryprivate void KeyDataTrans(){//关键点得数据值对应到曲线数据上foreach (KeyValuePairint, float item in keyListDatas){int key item.Key;float fValue item.Value;//myEditDatas[key] fValue;KeyDatasflag[key] 1; //关键帧所在的地方设置为1}//Listfloat fListTemp_X new Listfloat { };Listfloat fListTemp_Y new Listfloat { };foreach (KeyValuePairint, float item in keyListDatas){int key item.Key;float fValue item.Value;fListTemp_X.Add(key);fListTemp_Y.Add(fValue);}keyEditDatas_X fListTemp_X.ToArray();keyEditDatas_Y fListTemp_Y.ToArray();//三次样条插值PointClass[] points new PointClass[keyEditDatas_X.Length];for (int i 0; i keyEditDatas_X.Length; i){points[i] new PointClass();points[i].x keyEditDatas_X[i];points[i].y keyEditDatas_Y[i];}PointClass.DeSortX(points); //排序try{double[] xs new double[myEditDatas.Length];for (int i 0; i myEditDatas.Length; i){xs[i] i;}double[] Y DataInterpolation.SplineInsertPoint(points, xs, 1);if (Y.Length myEditDatas.Length){for (int i 0; i myEditDatas.Length; i){myEditDatas[i] (float)Y[i];}}}catch { }} 未使用插值的曲线 使用三次样条插值后曲线 使用三次样条插值后操作演示
2工程代码下载链接
代码仅个人使用
链接https://pan.baidu.com/s/1WLov3JLowmw_YS_wQT7QNw 提取码fi2f --来自百度网盘超级会员V4的分享
四、曲线数据导出和读取
1、数据导出
导出数据要求数据分三列第一列是行号、第二列是曲线数据、第三列是关键帧标志位。 1添加导出按钮
btnSplineDataExport_Click private void btnSplineDataExport_Click(object sender, EventArgs e){if (myEditDatas.Length 1){MessageBox.Show(请先添加数据, 提示);return;}//string[] newLines new string[myEditDatas.Length];for (int i 0; i myEditDatas.Length; i){if (KeyDatasflag[i] 1){newLines[i] L i.ToString() \t myEditDatas[i].ToString(0.00) \t 1;}else{newLines[i] L i.ToString() \t myEditDatas[i].ToString(0.00) \t 0;}//newLines[i] myEditDatas[i].ToString(0.00);}string path C:\Users\Administrator\Desktop\TestData.txt;using (System.IO.StreamWriter file new System.IO.StreamWriter(path, true)){foreach (string line in newLines){file.WriteLine(line);// 直接追加文件末尾换行 //file.Write(line);//直接追加文件末尾不换行}}MessageBox.Show(导出完成, 提示);} 曲线编辑和数据导出
2工程代码下载链接
代码仅个人使用
链接https://pan.baidu.com/s/1Gpbe-fJGOqLdj7VxFTDdcg 提取码vyyq --来自百度网盘超级会员V4的分享
2、读取导出的数据
1手动按钮创建曲线
将窗口登陆时添加的关键帧数据改成手动点击按钮生成。 btnDataCreate_Click private void btnDataCreate_Click(object sender, EventArgs e){//曲线编辑器数据dataLength int.Parse(txtDataLength.Text);myEditDatas new float[dataLength];KeyDatasflag new int[myEditDatas.Length];//字典集合中添加4个随机数据keyListDatas.Add(100 dataLength / 2, 40.0f);keyListDatas.Add(0, 0.0f);keyListDatas.Add(dataLength / 2, 10.0f);keyListDatas.Add(dataLength - 1, 0.0f);keyListDatas[dataLength / 2] 50.0f; //修改字典集合中的值KeyDataTrans();}
修改MainForm_Load private void MainForm_Load(object sender, EventArgs e){//timer1.Start();timer2.Start();cureDraw new SplineEdit(pictureBox1.Height, pictureBox1.Width);DrawCure();}
修改DrawCure() private void DrawCure(){if (pictureBox1.Height 0 pictureBox1.Width 0) //若窗口最小化时候则Height、Width都为0。DrawImage()创建图像会出错{cureDraw.Height pictureBox1.Height;cureDraw.Width pictureBox1.Width;}pictureBox1.Image cureDraw.DrawImage();//当前帧指示线cureDraw.DrawCurrentLine(last_CurrentValueX);if (isLeftButtonDowm){last_CurrentValueX currentValue_X;if (myEditDatas ! null){if (last_CurrentValueX myEditDatas.Length){last_CurrentValueX myEditDatas.Length;}}}//曲线编辑器if (keyListDatas.Count 0)//if (keyEditDatas_Y.Length 0) //绘制关键帧{cureDraw.DrawPoint(keyEditDatas_X, keyEditDatas_Y, editSplineColor, tensionSpline1, true);}if (dataLength 0)//if (myEditDatas.Length 0) //绘制曲线{cureDraw.DrawSpline(myEditDatas, editSplineColor, 0.5f, false);}} 2读取导出得关键帧数据
btnSplineDataRead() private void btnSplineDataRead_Click(object sender, EventArgs e){try{OpenFileDialog ofd new OpenFileDialog();ofd.Filter All files(*.*)|*.*|文本文件(*.csv)|*.csv|文本文件(*.txt)|*.txt;if (ofd.ShowDialog() ! DialogResult.OK){return;}int dataColumNums 0; //动作文件列表数int dataLineNums; //double[,] axisDataArrayRead;float[] axis1Datas;string[] lines File.ReadAllLines(ofd.FileName, Encoding.Default).ToArray();dataColumNums CharNum(lines[0], \t);dataLineNums lines.Length;axisDataArrayRead new double[dataColumNums, dataLineNums];axis1Datas new float[dataLineNums];//解析数据for (int i 0; i lines.Length; i){string[] seg lines[i].Split(\t); //英文逗号分隔符for (int j 1; j dataColumNums; j) // {axisDataArrayRead[j, i] Convert.ToDouble(seg[j]);}}//轴1数据for (int i 0; i lines.Length; i){axis1Datas[i] (float)axisDataArrayRead[1, i];}MessageBox.Show(读取完毕总共 dataLineNums.ToString() 行, 提示);//dataLength dataLineNums;myEditDatas new float[dataLength];KeyDatasflag new int[myEditDatas.Length];for (int i 0; i dataLength; i){myEditDatas[i] (float)axisDataArrayRead[1, i];KeyDatasflag[i] (int)axisDataArrayRead[2, i];if (KeyDatasflag[i] 1){keyListDatas.Add(i, myEditDatas[i]);}}}catch{MessageBox.Show(文件解析异常, 提示);}} 3工程代码下载链接
3
链接https://pan.baidu.com/s/1uj4xVkTCpGVTarcqiJCxGA 提取码w1o9 --来自百度网盘超级会员V4的分享
4
链接https://pan.baidu.com/s/1Ly3mKv2WZ9mfNCvjKAIDPA 提取码zydp --来自百度网盘超级会员V4的分享
五、全部工程下载
1、基本功能
https://download.csdn.net/download/panjinliang066333/88112693
2、核心功能
https://download.csdn.net/download/panjinliang066333/88117382