Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Rotate points via Transform  (Read 3588 times)

0 Members and 1 Guest are viewing this topic.

igor

  • Newbie
  • *
  • Posts: 8
    • View Profile
    • Email
Rotate points via Transform
« on: January 08, 2013, 10:18:12 am »
I'm make class, witch handle collision map for object. After changing origin, position or angle the update function invoke. This function should make the returnable vector (m_Current) with points in their positions on the global collision map. When I trying to rotate line ([0,0] [0,1] [0,2] [0,3]) at 45 degrees, it return wrong result.

getOrigin() and getPosition() return sf::Vector2u
getRotation() return int

void CollisionOutline::update() {

        m_Current = m_Original;

        sf::Transform matrix;

        matrix.translate(-(getOrigin().x), -(getOrigin().y)).rotate(getRotation());

        for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
                cell->x = static_cast<int>(matrix.transformPoint(cell->x, cell->y).x + 0.5);
                cell->y = static_cast<int>(matrix.transformPoint(cell->x, cell->y).y + 0.5);
        }

        for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
                cell->x += getPosition().x;
                cell->y += getPosition().y;
        }

}

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: Rotate points via Transform
« Reply #1 on: January 08, 2013, 05:34:53 pm »
I am unaware of SFML containing any rotational capabilities, and I would not depend on them if they do, as there are three different kinds of rotations, as such, I wrote my own rotational code, which you can be free to use:


void Being3D::PlusMatrix(sf::Vector3<float> XMatrix, sf::Vector3<float> YMatrix, sf::Vector3<float> ZMatrix){
    sf::Vector3<float> XMtransform(MultiplyByMatrix(_XMatrix, XMatrix, YMatrix, ZMatrix));
    sf::Vector3<float> YMtransform(MultiplyByMatrix(_YMatrix, XMatrix, YMatrix, ZMatrix));
    sf::Vector3<float> ZMtransform(MultiplyByMatrix(_ZMatrix, XMatrix, YMatrix, ZMatrix));

    _XMatrix = XMtransform;
    _YMatrix = YMtransform;
    _ZMatrix = ZMtransform;
    std::vector<Being3D*> c = _Children;
    for (unsigned int i=1; i < c.size();i++){
        c[i]->PlusMatrix(XMatrix, YMatrix, ZMatrix);
    }
}

void Being3D::ToMatrix(sf::Vector3<float> XMatrix, sf::Vector3<float> YMatrix, sf::Vector3<float> ZMatrix){
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //TODO: MAKE MORE EFFICIENT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    sf::Vector3<float> InverseMatrix[3];
    CoFactor(InverseMatrix, _XMatrix, _YMatrix, _ZMatrix);
    Transpose(InverseMatrix);

    PlusMatrix(InverseMatrix[0], InverseMatrix[1], InverseMatrix[2]);
    PlusMatrix(XMatrix, YMatrix, ZMatrix);
}

////////////////////
////////////////////
//    rotation    //
////////////////////
////////////////////

void Being3D::GlobalRotateX(float rotx){
    float cosx = cos(rotx);
    float sinx = sin(rotx);
    sf::Vector3<float> YMatrix(0,cosx,sinx);
    sf::Vector3<float> ZMatrix(0,-sinx,cosx);

    PlusMatrix(sf::Vector3<float> (1,0,0), YMatrix, ZMatrix);
}

void Being3D::GlobalRotateY(float roty){
    float cosy = cos(roty);
    float siny = sin(roty);
    sf::Vector3<float> XMatrix(cosy,0,-siny);
    sf::Vector3<float> ZMatrix(siny,0,cosy);

    PlusMatrix(XMatrix, sf::Vector3<float> (0,1,0), ZMatrix);
}

void Being3D::GlobalRotateZ(float rotz){
    float cosz = cos(rotz);
    float sinz = sin(rotz);
    sf::Vector3<float> XMatrix(cosz,sinz,0);
    sf::Vector3<float> YMatrix(-sinz,cosz,0);

    PlusMatrix(XMatrix, YMatrix, sf::Vector3<float> (0,0,1));
}

void Being3D::RotateX(float rotx){
    float cosx = cos(rotx);
    float sinx = sin(rotx);
    sf::Vector3<float> XMatrix (MultiplyByMatrix(sf::Vector3<float> (1,0,0), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> YMatrix (MultiplyByMatrix(sf::Vector3<float> (0,cosx,sinx), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> ZMatrix (MultiplyByMatrix(sf::Vector3<float> (0,-sinx,cosx), _XMatrix, _YMatrix, _ZMatrix));

    ToMatrix(XMatrix, YMatrix, ZMatrix);
}

void Being3D::RotateY(float roty){
    float cosy = cos(roty);
    float siny = sin(roty);
    sf::Vector3<float> XMatrix (MultiplyByMatrix(sf::Vector3<float> (cosy,0,-siny), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> YMatrix (MultiplyByMatrix(sf::Vector3<float> (0,1,0), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> ZMatrix (MultiplyByMatrix(sf::Vector3<float> (siny,0,cosy), _XMatrix, _YMatrix, _ZMatrix));

    ToMatrix(XMatrix, YMatrix, ZMatrix);
}

void Being3D::RotateZ(float rotz){
    float cosz = cos(rotz);
    float sinz = sin(rotz);

    sf::Vector3<float> XMatrix (MultiplyByMatrix(sf::Vector3<float> (cosz,sinz,0), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> YMatrix (MultiplyByMatrix(sf::Vector3<float> (-sinz,cosz,0), _XMatrix, _YMatrix, _ZMatrix));
    sf::Vector3<float> ZMatrix (MultiplyByMatrix(sf::Vector3<float> (0,0,1), _XMatrix, _YMatrix, _ZMatrix));

    ToMatrix(XMatrix, YMatrix, ZMatrix);
}
 
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

igor

  • Newbie
  • *
  • Posts: 8
    • View Profile
    • Email
Re: Rotate points via Transform
« Reply #2 on: January 09, 2013, 04:21:14 am »
I'm find one of the problems, but result still wrong:

for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
        cell->x = static_cast<int>(matrix.transformPoint(cell->x, cell->y).x + 0.5); // here cell->x modified
        cell->y = static_cast<int>(matrix.transformPoint(cell->x, cell->y).y + 0.5); // ... and used again
}

 
Also I'm find some solution on the StackOverflow, and wrote update without sf::Trasform.

http://stackoverflow.com/questions/7440900/function-to-rotate-a-point-around-another-point

Weeve thanks for the code, it's interesting, but can you give full code, because some functions are not defined here (I bad know English (you see) and English math terms, therefore it hard to me to understand it.)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10826
    • View Profile
    • development blog
    • Email
Re: Rotate points via Transform
« Reply #3 on: January 09, 2013, 04:48:52 am »
I am unaware of SFML containing any rotational capabilities, and I would not depend on them if they do, as there are three different kinds of rotations, as such, I wrote my own rotational code, which you can be free to use.
So you think it's better to rely on your unfinished code rather than on some well integrated and tested functionality of SFML you don't even know about? ???

Weeve thanks for the code, it's interesting, but can you give full code, because some functions are not defined here (I bad know English (you see) and English math terms, therefore it hard to me to understand it.)
Don't worry about it, he only provided a rotation functionality, which sf::Transform already provides, but didn't give a solution to your problem. ;)

Could you try to explain your problem again a bit more clearly?
The only thing I got is, that you have some sort of a CollisionMap (how is it defined?) and you want to rotate a line (from where to where and why?), other than that I didn't really understand what you want to do. :-\

You should really provide a complete and minimal example, otherwise it will be hard for us to see what you're actually doing.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

igor

  • Newbie
  • *
  • Posts: 8
    • View Profile
    • Email
Re: Rotate points via Transform
« Reply #4 on: January 09, 2013, 04:26:57 pm »
I think that full code in my case is no matter, but if you want: http://www.mediafire.com/?giz1xtn8626w2zj
Here are all need sources and the file witch contain points of outline and origin point of this.

Finally I'm find problem in rotation: it was rounding problem.

Now I have another problem: how to rotate point counterclockwise via sf::Transform, without inverting an angle ?

Look (green figure is original, blue figure is rotated on 45 degrees):

Good (via transform matrix): http://s2.ipicture.ru/uploads/20130109/jgY6v3Qb.jpg
Bad (via sf::Transform): http://s2.ipicture.ru/uploads/20130109/GN3NiStT.jpg

Good code:

for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
        cell->x -= getOrigin().x;
        cell->y -= getOrigin().y;
}

const double sin_val = std::sin(Castings::toRadians(getRotation()));
const double cos_val = std::cos(Castings::toRadians(getRotation()));

for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
        int new_x = static_cast<int>(std::floor((cell->x*cos_val + cell->y*sin_val) + 0.5));
        int new_y = static_cast<int>(std::floor((cell->y*cos_val - cell->x*sin_val) + 0.5));
        cell->x = new_x;
        cell->y = new_y;
}

Bad code:

sf::Transform matrix;

matrix.translate(getOrigin().x, getOrigin().y).rotate(getRotation());

for (std::vector<sf::Vector2i>::iterator cell = m_Current.begin(); cell != m_Current.end(); cell++) {
        int new_x = static_cast<int>(floor(matrix.transformPoint(cell->x, cell->y).x + 0.5));
        int new_y = static_cast<int>(floor(matrix.transformPoint(cell->x, cell->y).y + 0.5));
        cell->x = new_x;
        cell->y = new_y;
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10826
    • View Profile
    • development blog
    • Email
Re: Rotate points via Transform
« Reply #5 on: January 09, 2013, 05:26:32 pm »
Now I have another problem: how to rotate point counterclockwise via sf::Transform, without inverting an angle ?
Why wouldn't you want to invert the angle?
There are only two options, either invert it *somewhere* or add 180 to it, so the rotation goes around one more time.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

igor

  • Newbie
  • *
  • Posts: 8
    • View Profile
    • Email
Re: Rotate points via Transform
« Reply #6 on: January 09, 2013, 07:11:17 pm »
I hoped that sf::Transform offer some ways to specify non-standard orientations of coordinate system, seems that invert angle is only way to get counterclockwise rotation (Small notice: in term inverse angle I mean negative angle, non angle + 180).

Problem solved, I hope, thank you for your attention.