为了账号安全,请及时绑定邮箱和手机立即绑定

如何尽可能准确地绘制蝴蝶曲线?

如何尽可能准确地绘制蝴蝶曲线?

慕桂英3389331 2021-12-18 15:12:45
我想画一个蝶形线使用Java。这是上述曲线的参数方程:根据我在大学时的记忆,绘制参数方程的方法Java是下一个:public void paintComponent(Graphics g) {    super.paintComponent(g);    Graphics2D g2 = (Graphics2D)g;    g2.translate(300,300);    int x1,y1;    int x0 = 0;    int y0 = (int)(Math.E-2); //for x = 0, we get y = Math.E - 2    int nPoints = 1000;    g2.scale(30,-30);    for(int i=0;i<nPoints;i++) {        double t= 12*i*Math.PI/nPoints; //to make it between 0 and 12*PI.        x1=(int)(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));        y1 = (int)(Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));        g2.drawLine(x0,y0,x1,y1);        x0=x1;        y0=y1;    }}现在,这给了我下一个结果:好吧,这与预期的结果相差甚远。然后我决定尝试一下,Line2D.Double认为这会提供更准确的绘图。public void paintComponent(Graphics g) {    super.paintComponent(g);    Graphics2D g2 = (Graphics2D)g;    g2.translate(300,300);    double x1,y1;    double x0 = 0;    int nPoints = 500;    g2.scale(30,-30);    double y0 = Math.E-2;    for(int i=0;i<nPoints;i++) {        double t= 12*i*Math.PI/nPoints;        x1=(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));        y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));        g2.draw(new Line2D.Double(x0,y0,x1,y1));        x0=x1;        y0=y1;    }}这产生了下一个结果:好的,这肯定看起来更好,但肯定不是预期的结果。因此我问,有没有办法使用这个参数方程绘制最准确的曲线Java?它不必像上图那样 100% 看起来,而是最接近的。
查看完整描述

1 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

你的 scale 语句也会缩放你的线的宽度,导致你的曲线形状奇怪。有两种简单的方法可以解决这个问题:


减少线的宽度,例如到 0.01f:


Graphics2D g2 = (Graphics2D)g;

g2.translate(300,300);

double x1,y1;

double x0 = 0;

int nPoints = 500;

// Alternative 1 ---------------------

g2.scale(30,-30);

g2.setStroke(new BasicStroke(0.01f ));

// -----------------------------------

double y0 = Math.E-2;

for(int i=0;i<nPoints;i++) {

    double t= 12*i*Math.PI/nPoints;

    x1= (Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

    y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

    g2.draw(new Line2D.Double(x0,y0,x1,y1));

    x0=x1;

    y0=y1;

}  

这导致:

//img1.sycdn.imooc.com//61bd8a440001666f02090190.jpg

删除您的比例声明并使用其幅度缩放曲线,即使用关于您的 x 和 y 值的恒定前置因子,例如 -30:


Graphics2D g2 = (Graphics2D)g;

g2.translate(300,300);

double x1,y1;

double x0 = 0;

int nPoints = 500;

// Alternative 2 ---------------------

double amp = -30.0;

// -----------------------------------

double y0 = Math.E-2;

for(int i=0;i<nPoints;i++) {

    double t= 12*i*Math.PI/nPoints;

    // Alternative 2 ----------------------------------------------------------------------------------

    x1=amp*(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

    y1=amp*(Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

    // ------------------------------------------------------------------------------------------------

    g2.draw(new Line2D.Double(x0,y0,x1,y1));

    x0=x1;

    y0=y1;

}  

这导致(或多或少相同):

//img1.sycdn.imooc.com//61bd8a500001edb202090187.jpg

此外,您可以通过使用抗锯齿和增加 nPoints 来提高绘图的质量:


    Graphics2D g2 = (Graphics2D)g;

    // Optimization ------------------------------------

    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

            RenderingHints.VALUE_ANTIALIAS_ON);

    int nPoints = 1500;

    // -------------------------------------------------

    g2.translate(300,300);

    double x1,y1;

    double x0 = 0;

    // Alternative 1 ---------------------

    g2.scale(50,-50);

    g2.setStroke(new BasicStroke(0.01f ));

    // -----------------------------------

    double y0 = Math.E-2;

    for(int i=0;i<nPoints;i++) {

        double t= 12*i*Math.PI/nPoints;

        x1= (Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

        y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));

        g2.draw(new Line2D.Double(x0,y0,x1,y1));

        x0=x1;

        y0=y1;

    }  

这导致(看起来好多了):

//img1.sycdn.imooc.com//61bd8a5f000150ed03370294.jpg

到目前为止,两点之间的连接是一条直线。当然,您可以使用样条曲线(贝塞尔曲线等)进行进一步优化,但这可能并非易事。


查看完整回答
反对 回复 2021-12-18
  • 1 回答
  • 0 关注
  • 246 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信