Calculating vertices of a rotated rectangle

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Calculating vertices of a rotated rectangle

Post by short »

Hey guys, I am trying to calculate the vertices of a rotated rectangle (2D).

It's easy enough if the rectangle has not been rotated, I figured that part out.

If the rectangle has been rotated, I thought of two possible ways to calculate the vertices.
1) Figure out how to transform the vertices from local/object/model space (the ones I figured out below) to world space. I honestly have no clue, and if it is the best way then I feel like I would learn a lot from it if I could figure it out...

2) Use trig to somehow figure out where the endpoints of the rectangle are relative to the position of the rectangle in world space. This has been the way I have been trying to do up until now, I just haven't figured out how.

Here's the function that calculates the vertices thus far, thanks for any help :oops:

Code: Select all

void Rect::calculateVertices()
{
    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z), 
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z) );
    }
    else
    {
        // if the rectangle has been rotated..
    }

    //GLfloat theta = RAD_TO_DEG( atan( ((m_width/2) * m_scaleX) / ((m_height / 2) * m_scaleY) ) );
    //LOG->writeLn(&theta);

}
Last edited by short on Mon Oct 05, 2009 11:09 pm, edited 2 times in total.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Calculating vertices of a rotated rectangle

Post by short »

Solved.

I'll go ahead and post my solution in case it may be helpful to others. ;)

Code: Select all

void Rect::calculateVertices()
{
    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z), 
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z) );
    }
    else
    {
        Vertex TL = Vertex( 
            ((m_position.x - (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y + (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x - (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y + (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex TR = Vertex( 
            ((m_position.x + (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y + (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x + (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y + (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex BR = Vertex( 
            ((m_position.x + (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y - (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x + (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y - (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex BL = Vertex( 
            ((m_position.x - (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y - (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x - (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y - (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);


        setVertices( &TL, &TR, &BR, &BL );

    }
}
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
trufun202
Game Developer
Game Developer
Posts: 1105
Joined: Sun Sep 21, 2008 12:27 am
Location: Dallas, TX
Contact:

Re: [Solved] Calculating vertices of a rotated rectangle

Post by trufun202 »

Wow, what a coincidence. A buddy of mine at work was trying to find the exact same thing for a WPF app that he's working on.

We came up with a way around it, so we didn't have to worry about the verts, but it's cool to see it solved with trig.
-Chris

YouTube | Twitter | Rad Raygun

“REAL ARTISTS SHIP” - Steve Jobs
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: [Solved] Calculating vertices of a rotated rectangle

Post by short »

trufun202 wrote:Wow, what a coincidence. A buddy of mine at work was trying to find the exact same thing for a WPF app that he's working on.

We came up with a way around it, so we didn't have to worry about the verts, but it's cool to see it solved with trig.
Care to elaborate on how you guys did it?
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Calculating vertices of a rotated rectangle

Post by MarauderIIC »

short0014 wrote:Solved.

I'll go ahead and post my solution in case it may be helpful to others. ;)

Code: Select all

void Rect::calculateVertices()
{
    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z), 
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y + (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x + (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z),
        &Vertex( (m_position.x - (m_width / 2) * m_scaleX), (m_position.y - (m_height / 2) * m_scaleY), m_position.z) );
    }
    else
    {
        Vertex TL = Vertex( 
            ((m_position.x - (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y + (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x - (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y + (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex TR = Vertex( 
            ((m_position.x + (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y + (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x + (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y + (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex BR = Vertex( 
            ((m_position.x + (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y - (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x + (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y - (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);

        Vertex BL = Vertex( 
            ((m_position.x - (m_width / 2) * m_scaleX) * cos(DEG_TO_RAD(m_orientation))) - 
            ((m_position.y - (m_height / 2) * m_scaleY) * sin(DEG_TO_RAD(m_orientation))),
            
            ((m_position.x - (m_width / 2) * m_scaleX) * sin(DEG_TO_RAD(m_orientation))) +
            ((m_position.y - (m_height / 2) * m_scaleY) * cos(DEG_TO_RAD(m_orientation)))
            , m_position.z);


        setVertices( &TL, &TR, &BR, &BL );

    }
}
I know this is a bit off-topic, but you should probably..

Code: Select all

void Rect::calculateVertices()
{
    //Let the compiler do some copy-pasting or other fun const optimizations.
    //Also, easier to read.
    const int WIDTH_SCALE = (m_width / 2) * m_scaleX;
    const int HEIGHT_SCALE = (m_height / 2) * m_scaleY;

    const int LEFT = m_position.x - WIDTH_SCALE;
    const int RIGHT = m_position.x + WIDTH_SCALE;

    const int TOP  = m_position.y + HEIGHT_SCALE;
    const int BOTTOM = m_position.y - HEIGHT_SCALE;

    const int RADIANS = DEG_TO_RAD(m_orientation);

    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex(LEFT, TOP, m_position.z), 
        &Vertex(RIGHT, TOP, m_position.z),
        &Vertex(RIGHT, BOTTOM, m_position.z),
        &Vertex(LEFT, BOTTOM, m_position.z) );
    }
    else
    {
        Vertex TL = Vertex( 
            (LEFT * cos(RADIANS)) - 
            (TOP * sin(RADIANS)),
            
            (LEFT * sin(RADIANS)) +
            (TOP * cos(RADIANS))
            , m_position.z);

        Vertex TR = Vertex( 
            (RIGHT * cos(RADIANS)) - 
            (TOP * sin(RADIANS)),
            
            (RIGHT * sin(RADIANS)) +
            (TOP * cos(RADIANS))
            , m_position.z);

        Vertex BR = Vertex( 
            (RIGHT * cos(RADIANS)) - 
            (BOTTOM * sin(RADIANS)),
            
            (RIGHT * sin(RADIANS)) +
            (BOTTOM * cos(RADIANS))
            , m_position.z);

        Vertex BL = Vertex( 
            (LEFT * cos(RADIANS)) - 
            (BOTTOM * sin(RADIANS)),
            
            (LEFT * sin(RADIANS)) +
            (BOTTOM * cos(RADIANS))
            , m_position.z);


        setVertices( &TL, &TR, &BR, &BL );

    }
Isn't that better?
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: [Solved] Calculating vertices of a rotated rectangle

Post by short »

Ah, yes it is. Sometimes compiler optimizations I forget about. So, thanks :)

And yes, it's much better lol
Last edited by short on Thu Sep 24, 2009 11:54 am, edited 2 times in total.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: [Solved] Calculating vertices of a rotated rectangle

Post by qpHalcy0n »

Calculate sin and cos once. Those two functions are costlier than anything in that whole shabang there.
User avatar
trufun202
Game Developer
Game Developer
Posts: 1105
Joined: Sun Sep 21, 2008 12:27 am
Location: Dallas, TX
Contact:

Re: [Solved] Calculating vertices of a rotated rectangle

Post by trufun202 »

short0014 wrote:
trufun202 wrote:Wow, what a coincidence. A buddy of mine at work was trying to find the exact same thing for a WPF app that he's working on.

We came up with a way around it, so we didn't have to worry about the verts, but it's cool to see it solved with trig.
Care to elaborate on how you guys did it?
Well, we basically have an object (such as a rectangle) that is being rotated. Then we wanted to draw an outline around that object as it rotates - showing that the object is selected.

Before we introduced rotation, were were drawing the outline by getting the Top and Left of the object, along with it's Width and Height. But, when rotated, the canvas acts as a bounding box, and thus the Top and Left did not change. To solve this, we first thought that we'd have to calculate the vertices of the object after rotation. However, we just placed the outline on another canvas with a higher ZIndex, and rotated that canvas along with the object.

But, this was all in WPF...not sure how that's going to translate into your implementation...
-Chris

YouTube | Twitter | Rad Raygun

“REAL ARTISTS SHIP” - Steve Jobs
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: [Solved] Calculating vertices of a rotated rectangle

Post by short »

Ok, for anyone in using this I'll post the fastest version I can come up with:

Code: Select all

void Rect::calculateVertices()
{
    //Let the compiler do some copy-pasting or other fun const optimizations.
    //Also, easier to read.
    const GLfloat WIDTH_SCALE = (m_width / 2) * m_scaleX;
    const GLfloat HEIGHT_SCALE = (m_height / 2) * m_scaleY;

    const GLfloat LEFT = m_position.x - WIDTH_SCALE;
    const GLfloat RIGHT = m_position.x + WIDTH_SCALE;

    const GLfloat TOP  = m_position.y + HEIGHT_SCALE;
    const GLfloat BOTTOM = m_position.y - HEIGHT_SCALE;

    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex( LEFT, TOP, m_position.z), 
        &Vertex( RIGHT, TOP, m_position.z),
        &Vertex( RIGHT, BOTTOM, m_position.z),
        &Vertex( LEFT, BOTTOM, m_position.z) );
    }
    else
    {
        const GLfloat radians = (GLfloat)DEG_TO_RAD(m_orientation);
        const GLfloat cosn = (GLfloat)cos(radians);
        const GLfloat sinn = (GLfloat)sin(radians);

        Vertex TL = Vertex( (LEFT  * cosn) - (TOP * sinn)   , (LEFT  * sinn) + (TOP *    cosn), m_position.z );
        Vertex TR = Vertex( (RIGHT * cosn) - (TOP * sinn)   , (RIGHT * sinn) + (TOP *    cosn), m_position.z );
        Vertex BR = Vertex( (RIGHT * cosn) - (BOTTOM * sinn), (RIGHT * sinn) + (BOTTOM * cosn), m_position.z );
        Vertex BL = Vertex( (LEFT  * cosn) - (BOTTOM * sinn), (LEFT  * sinn) + (BOTTOM * cosn), m_position.z);

        setVertices( &TL, &TR, &BR, &BL );

    }
}
Marauder, I'm curious, do you know anything about how by making a variable const vs nonconstant the compiler can optimize it?

I'm very curious about this if you would care to explain a bit.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: [Solved] Calculating vertices of a rotated rectangle

Post by Falco Girgis »

Your code looks pretty good. I'm assuming that you needed this to actually rotate something to use with your OBB separating axis collision? So did you get it working with axis-aligned?

As for constant optimization, I really can't speak for x86, but many processors and architectures have special registers for frequently used constants. The compiler probably sees that it is a good idea to throw something defined as a const into one of these special registers. Remember, accessing a register is much faster than RAM.
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: [Solved] Calculating vertices of a rotated rectangle

Post by short »

GyroVorbis wrote:Your code looks pretty good. I'm assuming that you needed this to actually rotate something to use with your OBB separating axis collision? So did you get it working with axis-aligned?

As for constant optimization, I really can't speak for x86, but many processors and architectures have special registers for frequently used constants. The compiler probably sees that it is a good idea to throw something defined as a const into one of these special registers. Remember, accessing a register is much faster than RAM.
Yeah, I did need this for my separating axis collision. When I was working on implementing what you told me about the theorem I ran into the problem that I didn't know where the corners of the rectangles were. The only way I was getting the rectangle was to translate and draw the rectangle as normal.

This way, I never translate to draw the rectangle, I just calculate the new vertices and draw the rectangle with no translation. I honestly have no idea what kind of performance hit it will be calculating the rotated vertices vs just translating and drawing, then translating back. I think the translation method would be faster, but for now this is working great. I may revisit that issue after I get the seperating axis theorem implemented correctly.

.. As for actually implementing the theorem I'm going to work on it tonight after work, I have yet to learn linear algebra so your explanation seems a little bit cryptic to me.

However, I am learning a lot about vectors, what exactly an axis is, how to normalize said axis, and what a "normal vector" is. Maybe by the time I'm done I'll have a head start on all of this going into linear algebra :lol:

Oh, and that makes sense about the compiler using a special register for constants. It's actually very interesting :shock:
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: [Solved] Calculating vertices of a rotated rectangle

Post by avansc »

qp makes a very good point. so much, that if that was going to be called each game loop. i would strongly recommend to pre calculate sin and cos or all trig function.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: [Solved] Calculating vertices of a rotated rectangle

Post by MarauderIIC »

short0014 wrote:Marauder, I'm curious, do you know anything about how by making a variable const vs nonconstant the compiler can optimize it?
I probably used to. Found these in my bookmarks w/ tags "const optimization" : http://www.mi.uni-koeln.de/c/mirror/www ... c0092.html http://stackoverflow.com/questions/2122 ... ation-in-c http://gotw.ca/gotw/081.htm
qpHalcy0n wrote:Calculate sin and cos once. Those two functions are costlier than anything in that whole shabang there.
Whoops, I wasn't paying attention to the fact that he was doing that =)
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: [Solved] Calculating vertices of a rotated rectangle

Post by Bakkon »

This thread is awesome and I think I see how to modify it to work for any polygon with equal length edges. I definitely need to start playing with OpenGL.
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: [Solved] Calculating vertices of a rotated rectangle

Post by short »

avansc wrote:qp makes a very good point. so much, that if that was going to be called each game loop. i would strongly recommend to pre calculate sin and cos or all trig function.
Well, the way I have it set up is this function is only called upon if something changes (ie setScaleX or setOrientation or setPosition etc...)

I added a way to track the previous rotation, if the rotation has not been changed when this function is called, there is no reason to recalculate sin and cos, so I simply reuse them (they are the only two values of the array).

This is the best way I can think of doing this.
Anyone?

Code: Select all

void Rect::calculateVertices()
{
    const GLfloat WIDTH_SCALE = (m_width / 2) * m_scaleX;
    const GLfloat HEIGHT_SCALE = (m_height / 2) * m_scaleY;

    const GLfloat LEFT = m_position.x - WIDTH_SCALE;
    const GLfloat RIGHT = m_position.x + WIDTH_SCALE;

    const GLfloat TOP  = m_position.y + HEIGHT_SCALE;
    const GLfloat BOTTOM = m_position.y - HEIGHT_SCALE;

    if(m_orientation == 0) // if no rotation
    {
        setVertices(
        &Vertex( LEFT, TOP, m_position.z),
        &Vertex( RIGHT, TOP, m_position.z),
        &Vertex( RIGHT, BOTTOM, m_position.z),
        &Vertex( LEFT, BOTTOM, m_position.z) );
    }
    else
    {
        if(m_prev_orientation != m_orientation) // only calculate sin/cos if orientation has changed.
        {
            const GLfloat radians = (GLfloat)DEG_TO_RAD(m_orientation);
            const GLfloat cosn = (GLfloat)cos(radians);
            const GLfloat sinn = (GLfloat)sin(radians);
            m_pre_trig_calcs[COSN] = cosn;
            m_pre_trig_calcs[SINN] = sinn;
            m_prev_orientation = m_orientation;
        }

        Vertex TL = Vertex( (LEFT  * m_pre_trig_calcs[COSN]) - (TOP * m_pre_trig_calcs[SINN])   , 
            (LEFT  * m_pre_trig_calcs[SINN]) + (TOP *    m_pre_trig_calcs[COSN]), m_position.z );

        Vertex TR = Vertex( (RIGHT * m_pre_trig_calcs[COSN]) - (TOP * m_pre_trig_calcs[SINN])   ,
            (RIGHT * m_pre_trig_calcs[SINN]) + (TOP *    m_pre_trig_calcs[COSN]), m_position.z );

        Vertex BR = Vertex( (RIGHT * m_pre_trig_calcs[COSN]) - (BOTTOM * m_pre_trig_calcs[SINN]),
            (RIGHT * m_pre_trig_calcs[SINN]) + (BOTTOM * m_pre_trig_calcs[COSN]), m_position.z );

        Vertex BL = Vertex( (LEFT  * m_pre_trig_calcs[COSN]) - (BOTTOM * m_pre_trig_calcs[SINN]),
            (LEFT  * m_pre_trig_calcs[SINN]) + (BOTTOM * m_pre_trig_calcs[COSN]), m_position.z);


        setVertices( &TL, &TR, &BR, &BL );

    }
}
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
Post Reply