Обработка 3.5.3 Вращающиеся точки вокруг центральной точки Размер изображения уменьшается и исчезает - PullRequest
0 голосов
/ 23 февраля 2019

Моя проблема как в названии.Я пытаюсь написать простую в обработке игру с машиной, на которой можно водить в 2D плоскости.Я хотел создать вращение автомобиля, поскольку это кажется крайне важным, поэтому я сделал это, как описано здесь: Вращающиеся точки в 2D

Но моя реализация, похоже, немного дает сбой.Видите ли, когда я нажимаю левую стрелку вправо, машина фактически вращается, но сжимается в размерах при вращении и через несколько оборотов полностью исчезает.Можете ли вы показать мне, что мне здесь не хватает?Заранее спасибо!Код моих функций:

 class Point
{
   float x, y;
   Point(float xx, float yy)
   {
     x = xx;
     y = yy;
   }
   Point()
   {
      x = y = 0.0; 
   }
   void Rotate(Point center, float angle)
   {
     float s = sin(angle);
     float c = cos(angle);
      y = center.y + ((y-center.y) * c + (x-center.x) * s);
      x = center.x + ((x-center.x) * c - (y-center.y) * s);
   }
}
class Car
{
    Point LT;
    Point RT;
    Point LB;
    Point RB;
    Point center;
    float r;
    float acceleration;
    Car()
    {
       LT = new Point(10, 10);
       RT = new Point (30, 10);
       LB = new Point(10, 50);
       RB = new Point(30, 50);
       r = sqrt(pow(15-30, 2) + pow(25-10, 2));
    }
    Car(Point lt, Point rt, Point lb, Point rb)
    {
       LT = lt;
       RT = rt;
       LB = lb;
       RB = rb;
       center = new Point(abs((LT.x - RT.x)/2), abs((LT.y - LB.y)/2));
       r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
    }
    Car(Point Center, float w, float h)
    {
       center = Center;
       LT = new Point(center.x - w/2, center.y - h/2);
       RT = new Point (center.x + w/2, center.y - h/2);
       LB = new Point(center.x - w/2, center.y + h/2);
       RB = new Point(center.x + w/2, center.y + h/2);
       r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
    }
    void Show()
    {
       fill(45, 128, 156);
       beginShape(); 
       vertex(LT.x, LT.y);
       vertex(RT.x, RT.y);
       vertex(RB.x, RB.y);
       vertex(LB.x, LB.y);          
       endShape();
    }
    void Update()
    {

    }
    void Turn(float angle)
    {
      LT.Rotate(center, angle);
      RT.Rotate(center, angle);
      RB.Rotate(center, angle);
      LB.Rotate(center, angle);
    }
    void Accelerate(float accel)
    {

    }
}

В основном я использую только car.Show (), и я поворачиваюсь на -0,1 за левый клиок и 0,1 за правый клик

РЕДАКТИРОВАТЬ Если вы хотите увидеть весь код, посетите мой репозиторий github

1 Ответ

0 голосов
/ 23 февраля 2019

К сожалению, я не могу объяснить больше в данный момент, но вот более простой вариант с использованием одной из формул, на которые вы указали:

Car car = new Car();

void setup(){
  size(300,300);
  // this helps draw rectangles from centre (as opposed to corner (default))
  rectMode(CENTER);

  car.position.set(150,150);
}

void draw(){
  background(255);
  if(keyPressed){
    if(keyCode == UP){
      car.speed = 1;
    }
  }
  car.draw();
}

void keyPressed(){
  if(keyCode == LEFT){
    car.steer -= radians(10);
  }
  if(keyCode == RIGHT){
    car.steer += radians(10);
  }
}
void keyReleased(){
  if(keyCode == UP){
    car.speed = 0;
  }
}

class Car{

  PVector position = new PVector();
  PVector velocity = new PVector();

  float speed;
  float steer;

  void update(){
    // use the same polar to cartesian coordinates formulate for quick'n'dirty steering
    velocity.set(cos(steer) * speed,sin(steer) * speed);
    // update position based on velocity
    position.add(velocity);
  }

  void draw(){
    update();
    // use a nested coordinate system to handle translation and rotation for us
    // order of operations is important
    pushMatrix();
      translate(position.x,position.y);
      rotate(steer);
      rect(0,0,30,15);
    popMatrix();
  }
}

Обновление

Основная проблема с уменьшением точек состоит в том, что вы кумулятивно трансформируете точки при их вращении.После каждого преобразования нет истории того, чем были x, y.Вместо этого вы должны вернуть новую точку, которая преобразована, таким образом «запоминая» старую позицию x, y.

Bellow - это улучшенная версия вашего кода, за исключением двух вариантов конструктора.Надеемся, комментарии помогут:

Car car = new Car();

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

void draw(){

  if(keyCode == UP){
    if(keyPressed){
      car.Accelerate(1);
    }else{
      car.Accelerate(0);
    }
  }

  car.Update();

  background(255);
  car.Show();

}


void keyPressed(){
  if(keyCode == LEFT){
    car.Turn(radians(-3));
  }
  if(keyCode == RIGHT){
    car.Turn(radians(+3));
  }
}

class Point
{
   float x, y;
   Point(float xx, float yy)
   {
     x = xx;
     y = yy;
   }
   Point()
   {
      x = y = 0.0; 
   }

   Point Rotate(Point center, float angle)
   {
     float s = sin(angle);
     float c = cos(angle);
     // return a new point (a rotated copy), rather than overwriting this one
     return new Point(center.x + ((x-center.x) * c - (y-center.y) * s),
                      center.y + ((y-center.y) * c + (x-center.x) * s));
   }
   // translate by another point
   void AddToSelf(Point point){
     this.x += point.x;
     this.y += point.y;
   }
   // pretty print info when using println()
   String toString(){
     return "[Point x=" + x + " y="+ y +"]";
   }

}
class Car
{
    Point LT;
    Point RT;
    Point LB;
    Point RB;

    Point center;

    float r;
    float acceleration;

    // car angle: used to compute velocity and update vertices
    float angle;
    // car position: used to offset rendering position of the corners
    Point position;
    // car velocity: amount by which position translates
    Point velocity = new Point();

    Car()
    {
       float x = 10;
       float y = 10;
       float w = 40;
       float h = 20;
       // setup corners with no translation
       LT = new Point(0    , 0    );
       RT = new Point(0 + w, 0    );
       LB = new Point(0    , 0 + h);
       RB = new Point(0 + w, 0 + h);
       // setup initial position
       position = new Point(x,y);

       center = new Point(w / 2, h / 2);

       r = sqrt(pow(15-30, 2) + pow(25-10, 2));
    }
    //Car(Point lt, Point rt, Point lb, Point rb)
    //{
    //   LT = lt;
    //   RT = rt;
    //   LB = lb;
    //   RB = rb;
    //   center = new Point(abs((LT.x - RT.x)/2), abs((LT.y - LB.y)/2));
    //   r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
    //}
    //Car(Point Center, float w, float h)
    //{
    //   center = Center;
    //   LT = new Point(center.x - w/2, center.y - h/2);
    //   RT = new Point (center.x + w/2, center.y - h/2);
    //   LB = new Point(center.x - w/2, center.y + h/2);
    //   RB = new Point(center.x + w/2, center.y + h/2);
    //   r = sqrt(pow(center.x -LT.x, 2) + pow(center.y - LT.y, 2));
    //}
    void Show()
    {
       fill(45, 128, 156);
       beginShape(); 
       // render corners offset by the car position
       vertex(position.x + LT.x, position.y + LT.y);
       vertex(position.x + RT.x, position.y + RT.y);
       vertex(position.x + RB.x, position.y + RB.y);
       vertex(position.x + LB.x, position.y + LB.y);          
       endShape(CLOSE);
    }
    void Update()
    {
      // update velocity based on car angle and acceleration
      velocity.x = cos(angle) * acceleration;
      velocity.y = sin(angle) * acceleration;
      // update position based on velocity
      position.AddToSelf(velocity);

    }
    void Turn(float angle)
    {
      this.angle += angle;
      // replace the old point with the transformed points 
      // (rather than continuosly transforming the same point)
      LT = LT.Rotate(center, angle);
      RT = RT.Rotate(center, angle);
      RB = RB.Rotate(center, angle);
      LB = LB.Rotate(center, angle);
    }

    void Accelerate(float accel)
    {
      acceleration = accel;
    }
}
...