处理:如何使对象在圆形路径中移动?

时间:2016-01-17 19:14:53

标签: object geometry processing trigonometry calculus

我创建了一个类,我为我的程序定义了Shape对象。这些形状中的每一个都有一个围绕它绘制的透明椭圆(我在我的构造函数中定义),如果任何其他形状移动到该圆形椭圆区域,我希望该形状改变它的方向,使其在圆形路径中移动。

每个Shape对象都有一个已定义的radius属性(因为我在每个对象周围绘制椭圆),我想使用该值来确定Shape在碰撞时必须移动的圆形图案有多大。

请帮忙!非常感谢!

修改

正如我上面所说,我希望形状移动到圆形路径中。但是,我希望它只能在圆形路径中移动一次(意味着它绕一圈移动一次)然后我希望它继续在它编程的原始路径上。

2 个答案:

答案 0 :(得分:2)

简短的回答是,您必须使用基本触发来计算点之间的角度,然后使用更基本的触发来确定圆形路径上的后续点。

查看the Processing reference三角法部分以获取更多信息。

但基本上,如果你有两个点,你可以使用atan2()函数来计算它们之间的角度。您可以使用它来查找从圆心到形状的起始角度。

一旦你有了这个角度,你可以简单地增加它,然后使用cos()sin()找出新角度的xy坐标。

这是完成上述所有内容的基本草图:

PVector center;
float angle;
float radius;

void setup() {
  size(500, 500);
  center = new PVector(width/2, height/2);

  //get the initial point
  //for you, this would be the initial location of the object
  PVector point = new PVector(random(width), random(height));

  //find the angle between the points
  float deltaX = center.x - point.x;
  float deltaY = center.y - point.y;
  angle = atan2(deltaX, deltaY);

  //find the radius of the circle
  radius = dist(center.x, center.y, point.x, point.y);

  ellipseMode(RADIUS);
}

void draw() {
  background(0);

  //draw the center point
  ellipse(center.x, center.y, 10, 10);

  //find the point based on the angle
  float x = center.x + cos(angle)*radius;
  float y = center.y + sin(angle)*radius;

  //draw the traveling point
  ellipse(x, y, 10, 10);

  //increment the angle to move the point
  angle += PI/120;
}

答案 1 :(得分:1)

好吧,在我看到Kevin的帖子之前,我也做了一个。不使用对象,只是一个简单的程序示例。无论如何发布:)

   
PVector pos, speed, stored;
float diam = 40;
boolean wonder = false;
float angle = 0;


void setup() {
  size(300, 300);

  // arbitrary positioning and speeding
  pos = new PVector(-20, height/2);
  speed = new PVector(1, 0);
  noStroke();
}


void draw() {
  background(5);

  // normally increment speed
  if (!wonder) {
    pos.add(speed);
  } else {

    // if is to wonder...
    if (angle <= 360) {

      //get circle path by trig
      pos.x = stored.x + cos(radians(angle))*diam;
      pos.y = stored.y + sin(radians(angle))*diam;
    } else {

      // if the circle is complete
      // reset angle and stop wondering
      wonder = false;
      angle  = 0;
    }

    // increment angle
    angle++;
  }

  // draw
  ellipse(pos.x, pos.y, diam, diam);
}


void mouseClicked() {
  if (isOverCircle() ) {

    // store position where it has being clicked
    stored = pos.get();

    // off set the diam
    stored.x -= diam;

    // trig wondering
    wonder = true;
    angle = 0;
  }
}

boolean isOverCircle() {
  float disX = pos.x - mouseX;
  float disY = pos.y - mouseY;
  return sqrt(sq(disX) + sq(disY)) < diam/2;
}