【问题标题】:coordinate mapping in QtQt中的坐标映射
【发布时间】:2015-08-13 15:02:09
【问题描述】:

我一直在进行物理模拟,但在坐标方面遇到了一些问题。

我无法找到场景是如何映射的,以及当我不使用 mapToScene() 时映射到哪些对象;

我的代码如下:

球.cpp

Ball::Ball()
{
    //random start angle

    angle = (qrand() % 360);
    setRotation(angle);

    //set the speed
    speed = 5;


    //random start position
    int StartX = 0;
    int StartY = 0;


    if((qrand() % 1))
    {
        StartX = (qrand() % 200);
        StartY = (qrand() % 200);

    }
    else
    {
        StartX = (qrand() % 100);
        StartY = (qrand() % 100);
    }


    setPos(mapToScene(StartX,StartY));
    qDebug() << "xposition:" << pos().x();
    qDebug() << "yposition:" << pos().y();
    qDebug() << "xposition mapped:"  << mapToScene(pos()).x();
    qDebug() << "yposition mapped:" << mapToScene(pos()).y();

}

主窗口.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    scene = new QGraphicsScene (this);
    ui->graphicsView->setScene (scene);

    ui->graphicsView->setRenderHint(QPainter::Antialiasing);
    double sceneULx = -400;
    double sceneULy = 200;
    double scenewidth = 800;
    double sceneheight = 400;

    scene->setSceneRect(sceneULx, sceneULy,scenewidth,sceneheight);

    QPen mypen = QPen(Qt::red);

    QLineF TopLine(scene->sceneRect().topLeft(),scene->sceneRect().topRight());
    QLineF LeftLine(scene->sceneRect().topLeft(),scene->sceneRect().bottomLeft());
    QLineF RightLine(scene->sceneRect().bottomRight(),scene->sceneRect().topRight());
    QLineF BottomLine(scene->sceneRect().bottomLeft(),scene->sceneRect().bottomRight());

    scene->addLine(TopLine,mypen);
    scene->addLine(LeftLine,mypen);
    scene->addLine(RightLine,mypen);
    scene->addLine(BottomLine,mypen);

    int ItemCount = 5;
    for(int i = 0; i <ItemCount; i++)
    {
       Ball *item = new Ball();
       scene->addItem(item);
    }

    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()), scene,SLOT(advance()));
    timer->start(10);
}

目前我生成的所有对象都不在场景区域内,这对我来说没有任何意义,因为我认为场景的左上角是 0/0,当你进入正数时向下或向右。

qDebugs 也产生以下结果:

xposition: 25.6601
yposition: 22.306
xposition mapped: 30.392 
yposition mapped: 55.9751 
xposition: -56.6299 
yposition: 79.0004
xposition mapped: -136.607 
yposition mapped: 23.7579 
xposition: 31.6448 
yposition: 32.3822 
xposition mapped: 76.5177 
yposition mapped: 38.4172 
xposition: 50.017 
yposition: -97.4695 
xposition mapped: -59.4804 
yposition mapped: -93.9612 
xposition: -44.0378 
yposition: 9.25605 
xposition mapped: -33.8154 
yposition mapped: -34.5675

我真的找不到映射数字和未映射数字之间的相关性,而且映射数字有小数点也很奇怪,尽管我用 int 定义它们。

我希望有人能帮我解决我对这个程序坐标系的困惑。

【问题讨论】:

  • 我建议你用方便的度量构建一个非常简单的场景,试验它直到你理解坐标映射是如何工作的,然后尝试使用它。 Qt 经常有点不合逻辑。
  • 但是 mapToScene(pos().x()) 返回的东西怎么可能与 scenePos().x() 不同,它们应该是相同的,或者我对此的基本理解有问题?
  • 您的问题似乎有了答案。想补充一点,我在 Qt 坐标空间上制作了本教程,并在此处提供了小型演示代码示例。 youtube.com/watch?v=sY3WZvE9AV8&feature=youtu.be

标签: c++ qt mapping coordinates coordinate-systems


【解决方案1】:

我认为您对坐标系的想法是正确的,但您对代码中的疏忽感到困惑。

当一个 Ball 项目被创建时,在构造函数中,它会创建随机坐标,然后调用这个:

setPos(mapToScene(StartX,StartY));

正如mapToScene 的文档所述:-

将该项坐标系中的点point映射到场景坐标系,并返回映射后的坐标。

但是,代码在 Ball 的构造函数中执行,尚未添加到场景中,因此无法成功映射坐标,因为它没有父项,也没有可映射到的场景。

你可以在构造函数中调用setPos,但不能调用mapToScene

setPos(StartX,StartY);

没有父项,当item被添加到场景中时,它会匹配它的场景坐标(item->pos() == item->scenePos())

或者,创建一个 Ball 项目,将其添加到场景中,然后设置其位置。

for(int i = 0; i <ItemCount; i++)
{
   Ball *item = new Ball();
   scene->addItem(item);

   // note that mapToScene is irrelevant, since there is no parent item for the Ball.
   item->setPos(x, y); 
}

【讨论】:

    【解决方案2】:

    只是为了一个实验,你可以做以下技巧:

    //random start position
    int StartX = 100;
    int StartY = 100;
    
    setPos(mapToScene(StartX,StartY));
    qDebug() << "xposition:" << pos().x();
    qDebug() << "yposition:" << pos().y();
    qDebug() << "xposition mapped:"  << mapToScene(pos()).x();
    qDebug() << "yposition mapped:" << mapToScene(pos()).y();
    

    您会看到坐标仍然是随机的。基本上,您将坐标随机化 3 次,难怪没有相关性。

    也试试这个:

    double sceneULx = 0;
    double sceneULy = 0;
    double scenewidth = 800;
    double sceneheight = 400;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-09
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多