【问题标题】:Rotating an entire circle composed of individual arcs/sectors旋转由单个弧/扇区组成的整个圆圈
【发布时间】:2016-05-25 15:39:41
【问题描述】:

好的,所以我一直在尝试为 APCS 类编写游戏,并且我一直在使用 Processing.org/PApplet 来制作图形。我的主要图像是由具有不同颜色的各个弧组成的椭圆。但是,我想旋转整个圆(里面有圆弧)。这是我的代码:

public void setup() { 
         size(WIDTH, HEIGHT); background(22, 105, 250); 
} 

public void draw() { 
         drawLevel(level,18); 
}

private void drawLevel(int level, int numSectors) 

{   

        translate(50, -50);
        rotate((float)PI*level/numSectors);
        fill(255,0,0);
        arc(500, 375, 500, 500, 0, (TWO_PI)/18);


        rotate((float)PI*level/numSectors);
        translate(50, -50);
        fill(255,127,0);
        arc(500, 375, 500, 500, (TWO_PI)/18, (TWO_PI*2)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,255,0);
        arc(500, 375, 500, 500, (TWO_PI*2)/18, (TWO_PI*3)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(0,255,0);
        arc(500, 375, 500, 500, (TWO_PI*3)/18, (TWO_PI*4)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(0,0,255);
        arc(500, 375, 500, 500, (TWO_PI*4)/18, (TWO_PI*5)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(75,0,130);
        arc(500, 375, 500, 500, (TWO_PI*5)/18, (TWO_PI*6)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(139,0,255);
        arc(500, 375, 500, 500, (TWO_PI*6)/18, (TWO_PI*7)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,0,0);
        arc(500, 375, 500, 500, (TWO_PI*7)/18, (TWO_PI*8)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,127,0);
        arc(500, 375, 500, 500, (TWO_PI*8)/18, (TWO_PI*9)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,255,0);
        arc(500, 375, 500, 500, (TWO_PI*9)/18, (TWO_PI*10)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(0,255,0);
        arc(500, 375, 500, 500, (TWO_PI*10)/18, (TWO_PI*11)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(0,0,255);
        arc(500, 375, 500, 500, (TWO_PI*11)/18, (TWO_PI*12)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(75,0,130);
        arc(500, 375, 500, 500, (TWO_PI*12)/18, (TWO_PI*13)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(139,0,255);
        arc(500, 375, 500, 500, (TWO_PI*13)/18, (TWO_PI*14)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,0,0);
        arc(500, 375, 500, 500, (TWO_PI*14)/18, (TWO_PI*15)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,127,0);
        arc(500, 375, 500, 500, (TWO_PI*15)/18, (TWO_PI*16)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(255,255,0);
        arc(500, 375, 500, 500, (TWO_PI*16)/18, (TWO_PI*17)/18);

        //rotate((float)PI*level/numSectors);
        //translate(50, -50);
        fill(0,255,0);
        arc(500, 375, 500, 500, (TWO_PI*17)/18, (TWO_PI*18)/18);

}

我将平移和旋转作为 cmets,但我不确定如何旋转整个事物。当我运行translate()rotate() 方法时,它只运行一次(应该会发生),但是当我尝试将它用于第二个弧时,它与第一个弧重叠并且它以非常奇怪的方式居中。有人可以帮助“动画”它并循环它所需的循环以及如何更改rotate()translate() 方法吗?请,谢谢!

【问题讨论】:

  • 第一个 translate 和 rotate 方法完美运行,所以我的问题是如何保持圆旋转以及如何使 translate 和 rotate 方法的其他实例适用于其他弧。
  • 你能提供一个minimal reproducible example吗?换句话说,你能发布你的setup()draw() 函数吗?
  • 是的,这是我的 setup() 方法: public void setup() { size(WIDTH, HEIGHT);背景(22、105、250); }
  • 这是我的 draw() 方法: public void draw() { drawLevel(level,18); }
  • 另外,对不起我的格式,这是我第一次来这里。

标签: eclipse processing


【解决方案1】:

让我们从一个更简单的例子开始:

void setup() {
  size(500, 500);
}

void draw() {
  background(0);
  drawCircle();
}

void drawCircle() {
  fill(255, 0, 0);
  arc(width/2, height/2, 500, 500, radians(0), radians(180));

  fill(0, 0, 255);
  arc(width/2, height/2, 500, 500, radians(180), radians(360));
}

现在我们有了这个,我们可以谈谈旋转圆圈了。有两种主要方法可以做到这一点。

选项 1:依靠 translate()rotate() 函数为您进行轮换。

请注意,如果您这样做,您要么需要平移、旋转、然后取消平移,要么需要在原点绘制所有内容。

这里是使用翻译、旋转、取消翻译的方法:

void drawCircle() {

  translate(width/2, height/2);
  rotate(TWO_PI*mouseX/width);
  translate(-width/2, -height/2);

  fill(255, 0, 0);
  arc(width/2, height/2, 500, 500, radians(0), radians(180));

  fill(0, 0, 255);
  arc(width/2, height/2, 500, 500, radians(180), radians(360));
}

请注意,在这种情况下,我将平移到圆的中心,然后进行旋转,然后在绘制圆之前平移回左上角。 您的代码没有这样做,我认为这是您的主要问题之一。

这里使用的是原点方法:

void drawCircle() {

  translate(width/2, height/2);
  rotate(TWO_PI*mouseX/width);

  fill(255, 0, 0);
  arc(0, 0, 500, 500, radians(0), radians(180));

  fill(0, 0, 255);
  arc(0, 0, 500, 500, radians(180), radians(360));
}

请注意,在这种情况下,我在原点绘制弧线。但由于我没有不翻译,所以原点位于屏幕的中心。

您的代码似乎混合了这些方法,这就是它不起作用的原因。另请注意,如果您想旋转圆,您只需调用一次rotate()旋转每条圆弧没有意义,因为您已经在计算它们的旋转(您的数学涉及TWO_PI)。

选项 2: 您可以自己跟踪轮换,而不是使用 translate()rotate()。这特别容易,因为您已经将角度传递给 arc() 函数。

这是这种方法:

void drawCircle() {

  float startAngle = 360 * mouseX / width;

  fill(255, 0, 0);
  arc(width/2, height/2, 500, 500, radians(startAngle), radians(startAngle+180));

  fill(0, 0, 255);
  arc(width/2, height/2, 500, 500, radians(startAngle+180), radians(startAngle+360));
}

请注意,我不再需要对 rotate()translate() 大惊小怪了,因为我正在自己计算轮换。

您采用哪种方法实际上取决于最适合您的想法。但是您当前的代码似乎是几种方法的奇怪组合,这就是它不起作用的原因。

【讨论】:

  • 谢谢先生!这真的很有帮助!
  • 现在,在这之后,我可以使用 for 或 while 循环来保持它的旋转吗?我不确定如何将循环合并到这里。
  • 什么?!没有积分?你也想给你的论文打分并给你一个A吗??
  • @rick.chat 当然。我的示例使用mouseX,但您可以使用任何变量,然后随心所欲地递增它。尝试在我的示例中使用 frameCount 而不是 mouseX
  • @gpasch 我不确定我明白你在说什么。你在和谁说话?
猜你喜欢
  • 2019-04-25
  • 2015-09-30
  • 2013-11-25
  • 1970-01-01
  • 2014-11-20
  • 2021-07-30
  • 2021-02-22
  • 2013-07-05
  • 1970-01-01
相关资源
最近更新 更多