圆内角的高效计算,求解0、45、90、135、180、225、270和305度的位置

问题描述 投票:0回答:0

问题是,当一个函数被调用时,它把一个角度放在一个列表中。

然后,当调用另一个函数时,它会读取该列表。变量“PlayerAngle”是此列表中的第一个角度,称为“occupiedRotations”。

occupiedRotations 列表总是第一个元素,即“playerAngle”。

列表“occupiedRotations”必须是浮点数列表。

这是我对这个问题的 C++ (SFML) 实现 - 一个完整的函数(实际上不是函数,而是语句,但我们称它为函数):

if (currentlyPlacing!="None") {
    playerPart placePlayerPart = playerPart(0,currentlyPlacing);
    float y = sf::Mouse::getPosition().y - player.getPosition().y - player.getRadius() + moveOffset.y, x = sf::Mouse::getPosition().x - player.getPosition().x - player.getRadius() + moveOffset.x;
    float angle=atan2(y,x)*180/_Pi;
    float nearestAngle = playerParts.at(0).shape.getRotation();
    set<float> occupiedRotations;
    for (playerPart fplayerPart : playerParts) {
        occupiedRotations.insert(fplayerPart.shape.getRotation());
    }float orna=nearestAngle;
    while (nearestAngle < angle-22.5) {
        nearestAngle += 45;
    }while (nearestAngle > angle+22.5) {
        nearestAngle -= 45;
    }
    while (abs(nearestAngle-orna)>=360) { // stabilizing the angle (instead of 540 it becomes 180)
        if(nearestAngle-orna>=360){nearestAngle-=360;}
        else if(nearestAngle-orna<=-360){nearestAngle+=360;}
    }
    while (!isInVector(occupiedRotations,nearestAngle)) {
        vector<float> unoccupiedRotations;
        float playerAngle = *occupiedRotations.begin();
        for (float i = playerAngle - 360; i < playerAngle + 360; i += 45) {
            if (!isInVector(occupiedRotations,i)&&!isInVector(occupiedRotations,i-360)&&!isInVector(occupiedRotations,i+360)) {
                unoccupiedRotations.push_back(i);
            }
        }
        nearestAngle=findClosestNumber(unoccupiedRotations,nearestAngle);
    }
    placePlayerPart.shape.setRotation(nearestAngle);
    placePlayerPart.shape.setPosition(width / 2 + moveOffset.x + 85 * cos(nearestAngle * _Pi / 180), height / 2 + moveOffset.y + 85 * sin(nearestAngle * _Pi / 180));
    if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
        placePlayerPart.degreesOffset = playerParts.at(0).shape.getRotation()-nearestAngle;
        playerParts.push_back(placePlayerPart);
    }
    window.draw(placePlayerPart.shape);
}

是的,我知道这是一个写得不好的代码片段,但这只是一个草率的想法(老 4 个月我当时真的想解决它但一直在拖延),我最终会缩短它并使其更具可读性。

查找最接近的数字函数:

template <class T> T findClosestNumber(vector<T> numbers, T findValue) {
    T closest = numbers[0];
    for (int i = 1; i < numbers.size(); ++i) {
        if (abs(numbers[i] - findValue) < abs(closest - findValue)) {
            closest = numbers[i];
        }
    }
    return closest;
}

而 isInVector 函数只是 std::count 但在函数中使其更短。

我很难找到这个问题的解决方案,因为它以某种方式计算不正确。

在我当前的实施中我做错了什么?

c++ math logic trigonometry
© www.soinside.com 2019 - 2024. All rights reserved.