c# – 帮助分析软件程序如何构建Bezier曲线

c# – 帮助分析软件程序如何构建Bezier曲线,第1张

概述我试图了解由cambridgesoft开发的行业领先的化学工具ChemDraw如何构建Bezier曲线,以便我可以手动将Bezier曲线点从其他程序/例程(例如自制的Delphi / C#实用程序)转换为可以识别ChemDraw的曲线数据.在开始之前,我必须承认我在询问某个黑盒子内部如何工作,因此想要为任何麻烦道歉并感谢任何帮助! 我在ChemDraw中制作了四种最简单的Bezier曲线,并将它们 我试图了解由cambrIDgesoft开发的行业领先的化学工具ChemDraw如何构建BezIEr曲线,以便我可以手动将BezIEr曲线点从其他程序/例程(例如自制的Delphi / C#实用程序)转换为可以识别ChemDraw的曲线数据.在开始之前,我必须承认我在询问某个黑盒子内部如何工作,因此想要为任何麻烦道歉并感谢任何帮助!

我在ChemDraw中制作了四种最简单的BezIEr曲线,并将它们保存为.CDXML文件,其曲线部分最后粘贴了. .CDXML文件和相应的图片都可以从fileserve下载. Download Bezier_curve_ChemDraw_sample here. ChemDraw trial edition can be downloaded here.

问题

问题1.例如,以“线”类型的曲线点为例,我在制作此曲线时总共有两个点.为什么ChemDraw会为它存储六个积分? ChemDraw如何准确地解释这些要点?其他三种类型存在同样的问题,最多使用四个显式点.

问题2.如果在ChemDraw中显示“BezIEr曲线使用三点 – 第一类型”的内容,可以看到第一个点不能是(12.22,104.25).我的意思是,它的X坐标明显大于12.为什么会发生这种情况? ChemDraw会对数据进行一些转换吗? “使用四点的贝塞尔曲线”存在同样的问题.

问题3.似乎CurvePoints属性末尾的额外空白字符有所不同.有什么区别?

有人可以告诉我这些问题吗?

ChemDraw .CDXML文件中的曲线部分

============行==============

<curve   ID="2"   Z="1"   ArrowheadType="SolID"   CurvePoints="143.47 116.25 143.47 116.25 143.47 116.25 300.22 117.75 300.22 117.75 300.22 117.75"   />

============贝塞尔曲线使用三点 – 第一类==============

<curve   ID="2"   Z="1"   ArrowheadType="SolID"   CurvePoints="12.22 104.25 121.72 106.5 231.22 108.75 230.47 204 230.47 204 230.47 204"   />

============贝塞尔曲线使用三点 – 第二类==============

<curve   ID="2"   Z="1"   ArrowheadType="SolID"   CurvePoints="134.47 97.5 134.47 97.5 134.47 97.5 231.22 60.75 229.72 109.5 228.22 158.25"   />

============贝塞尔曲线使用四点==============

<curve   ID="2"   Z="1"   ArrowheadType="SolID"   CurvePoints="5.47 93.75 123.22 93.75 240.97 93.75 351.22 177.75 236.47 177.75 121.72 177.75"    />

示例C#程序生成相同的曲线

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.linq;using System.Text;using System.windows.Forms;namespace WinForms_2_DrawBezIEr{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        private voID Form1_Load(object sender,EventArgs e)        {            Text = "Draw BezIEr Curve";        }        private voID Form1_Paint(object sender,PaintEventArgs e)        {            // DrawBezIEr_1(this,e);            // DrawBezIEr_2(this,e);            // DrawBezIEr_3(this,e);             DrawBezIEr_4(this,e);        }        private voID DrawBezIEr_1(object sender,PaintEventArgs e)        {            Pen l_pen = new Pen(color.Black);            PointF l_pt1 = new PointF(143.47f,116.25f);            PointF l_pt2 = new PointF(l_pt1.X,l_pt1.Y);            PointF l_pt3 = new PointF(l_pt1.X,l_pt1.Y);            PointF l_pt4 = new PointF(300.22f,117.75f);            PointF l_pt5 = new PointF(l_pt4.X,l_pt4.Y);            PointF l_pt6 = new PointF(l_pt4.X,l_pt4.Y);            PointF[] l_pts = new PointF[6];            l_pts[0] = l_pt1;            l_pts[1] = l_pt2;            l_pts[2] = l_pt3;            l_pts[3] = l_pt4;            l_pts[4] = l_pt5;            l_pts[5] = l_pt6;            // e.Graphics.DrawBezIEr(l_pen,l_pt1,l_pt2,l_pt5,l_pt6);            e.Graphics.DrawBezIEr(l_pen,l_pt3,l_pt4,l_pt6); // As suggested by Dani            // e.Graphics.DrawBezIErs(l_pen,l_pts);        }        private voID DrawBezIEr_2(object sender,PaintEventArgs e)        {            Pen l_pen = new Pen(color.Black);            PointF l_pt1 = new PointF(12.22f,104.25f);            PointF l_pt2 = new PointF(121.72f,106.5f);            PointF l_pt3 = new PointF(231.22f,108.75f);            PointF l_pt4 = new PointF(230.47f,204f);            PointF l_pt5 = new PointF(l_pt4.X,l_pt4);            e.Graphics.DrawBezIEr(l_pen,l_pts);        }        private voID DrawBezIEr_3(object sender,PaintEventArgs e)        {            Pen l_pen = new Pen(color.Black);            PointF l_pt1 = new PointF(134.47f,97.5f);            PointF l_pt2 = new PointF(l_pt1.X,l_pt1.Y);            PointF l_pt4 = new PointF(231.22f,60.75f);            PointF l_pt5 = new PointF(229.72f,109.5f);            PointF l_pt6 = new PointF(228.22f,158.25f);            PointF[] l_pts = new PointF[6];            l_pts[0] = l_pt1;            l_pts[1] = l_pt2;            l_pts[2] = l_pt3;            l_pts[3] = l_pt4;            l_pts[4] = l_pt5;            l_pts[5] = l_pt6;            // e.Graphics.DrawBezIEr(l_pen,l_pts);        }        private voID DrawBezIEr_4(object sender,PaintEventArgs e)        {            Pen l_pen = new Pen(color.Black);            PointF l_pt1 = new PointF(5.47f,93.75f);            PointF l_pt2 = new PointF(123.22f,93.75f);            PointF l_pt3 = new PointF(240.97f,93.75f);            PointF l_pt4 = new PointF(351.22f,177.75f);            PointF l_pt5 = new PointF(236.47f,177.75f);            PointF l_pt6 = new PointF(121.72f,177.75f);            PointF[] l_pts = new PointF[6];            l_pts[0] = l_pt1;            l_pts[1] = l_pt2;            l_pts[2] = l_pt3;            l_pts[3] = l_pt4;            l_pts[4] = l_pt5;            l_pts[5] = l_pt6;            // e.Graphics.DrawBezIEr(l_pen,l_pts);        }    }}

但是,我无法使此C#实用程序生成与ChemDraw显示相同的曲线,但第一个line类型除外.

解决方法 它使用标准贝塞尔曲线算法,可以采用任意数量的点来构建曲线.看看 Bézier curve

编辑:
C#DrawBezIEr仅支持二次(四点)贝塞尔曲线.您将使用以下四点贝塞尔曲线转换为C#:

float[] CurvePoints = GetCurvePoints();DrawBezIEr(Pen,CurvePoints[0],CurvePoints[1],CurvePoints[4],CurvePoints[5],CurvePoints[6],CurvePoints[7],CurvePoints[10],CurvePoints[11]);

GetCurvePoints()只是为您提供CurvePoints xml属性中的点列表.

编辑2:
代码重现最后一条曲线的所有曲线:

using System;using System.Drawing;using System.windows.Forms;using System.linq;using System.Collections.Generic;public class BezIEr : Form{    static public voID Main ()    {        Application.Run (new BezIEr ());    }    protected overrIDe voID OnPaint (PaintEventArgs e)    {        // The input with all points        string CurveDataString = "5.47 93.75 123.22 93.75 240.97 93.75 351.22 177.75 236.47 177.75 121.72 177.75";        string[] CurveDataStringParts = CurveDataString.Split(' ');        int[] Keep = {2,3,4,5,6,7,8,9};        float[] CurveData = (from i in Keep select float.Parse(CurveDataStringParts[i])).ToArray();        e.Graphics.DrawBezIEr(Pens.Black,CurveData[0],CurveData[1],CurveData[2],CurveData[3],CurveData[4],CurveData[5],CurveData[6],CurveData[7]);        for(int i = 0; i < CurveData.Length; i += 2)        {            e.Graphics.FillEllipse(Brushes.Black,new RectangleF(CurveData[i] - 2,CurveData[i + 1] - 2,4));        }        base.OnPaint (e);    }}

结果:

总结

以上是内存溢出为你收集整理的c# – 帮助分析软件/程序如何构建Bezier曲线全部内容,希望文章能够帮你解决c# – 帮助分析软件/程序如何构建Bezier曲线所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1244990.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存