Page 1 of 1

2D: Collision, Rotation, Scale, and more IN CANVAS

PostPosted: Fri Feb 15, 2013 8:47 pm
by EvanAgain
3D Engine for GE Canvas:
viewtopic.php?f=6&t=7259



I had this idea to make a really cool game and it had me thinking about Polygons: Rotation and Scaling. I never took geometry so I don't even know where to begin?!

So I thought.. "Look up Canvas functions!" And I ran into a wall. These functions while they have elements of what I am looking for all require a 3D model. I am not so interested in 3D. But I love this engine and would be grateful for anyone to tell me about how it works. I looked at the code myself and just can't grasp it. It's lacking commenting. I am a noob.


Really, what I would like to be able to have is a series of functions for Drawing, Rotating, and Scaling 2D polygons. Preferred just triangles. But I want to be able to choose the point of rotation. I have been searching google for anything about the sorts and come up with nothing but a algorithm for rotation that I don't understand.

A lead, a hand, a piece of anything. I am not expecting anyone to do work for me, just that I need these 3 functions and I have no possible understanding of how to create them on my own.


PSUEDOCODE:
Code: Select all
struct Triangle
{
   p1;
   p2;
   p3;
}

Triangle tri1;

void Rotate_Triangle(Triangle* triangle, int pivotPoint)
{
    //Rotation algorithm
}

void Scale_Triangle(Triangle* triangle, int scaleAmount)
{
     //Scale algorithm
}

void Update_Canvas()
{
    //draw functions
}


Re: Help! I can't understand this code!!

PostPosted: Sat Feb 16, 2013 12:58 am
by skydereign
Okay, what you want is mostly linear algebra, namely matrix multiplication. You can rotate, scale, and various other transformations by multiplying your point by another matrix. Depending on what space you are in, you use a 2d or 3d matrix. Do you understand how matrix multiplication works?

You've probably already come across this page, but it is good to look at once you've started figuring other things out.
http://en.wikipedia.org/wiki/Transformation_matrix#Examples_in_2D_graphics

To rotate around a point that is not the origin, you must translate the object so the center becomes that point, and then do the rotation (and then translate it back to its original position). Translation is simple, as you just add to the x, y values. The rotation is specified in the above link, and involves multiplying by the rotation matrix.

Re: Help! I can't understand this code!!

PostPosted: Sat Feb 16, 2013 1:39 am
by EvanAgain
Thank!

This is what I tried before I came here and this is the outcome:

Code: Select all

struct Vector2d;

typedef struct Vector2d

{
    double x;
    double y;
}Vector2d;

double a;

int RunThisMany = 50;

Vector2d Point1 = {150,150};
Vector2d Point2 = {150,50};

void FindNewVector(double *old_x, double *old_y, double theta)
{
    double new_x;
    double new_y;
    new_x = cos(theta) * (*old_x) - sin(theta) * (*old_y);
    new_y = sin(theta) * (*old_x) + cos(theta) * (*old_y);
 
    (*old_x) = new_x;
    (*old_y) = new_y;
}

void Update_Canvas()
{
    //erase(0,0,0,0);
    setpen(255,255,255,0,2);
    moveto(Point1.x,Point1.y);
    lineto(Point2.x,Point2.y);
    FindNewVector(&Point2.x, &Point2.y, a);
    a = a + .001;
    if(a == 360)
    {
        a = 0;
    }
}

Re: Help! I can't understand this code!!

PostPosted: Sat Feb 16, 2013 6:24 am
by skydereign
EvanAgain wrote:This is what I tried before I came here and this is the outcome:

Not sure if you were looking for input on that, but here's some. gE's trig functions require radians, so you need to use degtorad to convert it. Currently your a variable is in degrees. The other thing is if you wanted a normal rotation, you would need to rotate both points, not just point2. That way the entire line rotates, instead of just the second point which changes the structure of the line. And that currently rotates around point (0,0), but can be easily converted to rotate around another point by subtracting it before the matrix multiplication, and adding it back afterwards.
Code: Select all
void FindNewVector(double *old_x, double *old_y, int rx, int ry, double theta)
{ // make sure theta is in radians when calling this, or convert within the function
    double new_x;
    double new_y;
    (*old_x)-=rx; // first subtracted
    (*old_y)-=ry;
    new_x = cos(theta) * (*old_x) - sin(theta) * (*old_y);
    new_y = sin(theta) * (*old_x) + cos(theta) * (*old_y);
 
    (*old_x) = new_x+rx; // added back
    (*old_y) = new_y+ry;
}

Re: Help! I can't understand this code!!

PostPosted: Sat Feb 16, 2013 7:17 pm
by EvanAgain
THANKS!!

I couldn't figure out what was wrong! I still don't understand why it works, but now it works!

Code: Select all
#define PI 3.141592

struct Vector2d;

typedef struct Vector2d

{
    double x;
    double y;
}Vector2d;


struct Triangle;
typedef struct Triangle
{
    Vector2d Point1;
    Vector2d Point2;
    Vector2d Point3;
}Triangle;




double Rad = 3;
Vector2d Pivot = {100,100};

Triangle Poly;

void FindNewVector(double *old_x, double *old_y, int rx, int ry, double theta)
{
    double new_x;
    double new_y;
    (*old_x)-=rx; // first subtracted
    (*old_y)-=ry;

    //Converted
    theta = theta * PI / 180;
 
    new_x = cos(theta) * (*old_x) - sin(theta) * (*old_y);
    new_y = sin(theta) * (*old_x) + cos(theta) * (*old_y);
 
    (*old_x) = new_x+rx; // added back
    (*old_y) = new_y+ry;
}

void RotateTriangle(Triangle *tri)
{
    FindNewVector(&tri->Point1.x, &tri->Point1.y, Pivot.x, Pivot.y, Rad);
    FindNewVector(&tri->Point2.x, &tri->Point2.y, Pivot.x, Pivot.y, Rad);
    FindNewVector(&tri->Point3.x, &tri->Point3.y, Pivot.x, Pivot.y, Rad);
}

void DrawTriangle(Triangle *tri)
{
    moveto(tri->Point1.x,tri->Point1.y);
    lineto(tri->Point2.x,tri->Point2.y);
    lineto(tri->Point3.x,tri->Point3.y);
    lineto(tri->Point1.x, tri->Point1.y);
}
 
 

void Update_Canvas()
{
    erase(0,0,0,0);
 
    setpen(255,255,255,0,2);
    RotateTriangle(&Poly);
    DrawTriangle(&Poly);
 
}

void Init_Poly()
{
    Poly.Point1.x =  100;
    Poly.Point1.y =  100;
    Poly.Point2.x =  100;
    Poly.Point2.y =  150;
    Poly.Point3.x =  150;
    Poly.Point3.y =  150;
 
    Pivot.x = (Poly.Point1.x + Poly.Point2.x + Poly.Point3.x) /3;
    Pivot.y = (Poly.Point1.y + Poly.Point2.y + Poly.Point3.y) /3;
}


With this code, I figured it out, now it rotates properly but it seems that "Rad" (not sure if thats properly named) seems to control the velocity of the rotation.

I understand that it controls the amount of rotation per function call but should I be calling Update_Canvas every frame? Is their a better way of doing this? Currently, Update_Canvas is in the Canvas->Draw Actor.

Also, if I had two canvas and I was swapping them like a buffer, would that improve the visual performance? Would it make the smoother?

Re: Help! I can't understand this code!!

PostPosted: Sat Feb 16, 2013 9:08 pm
by skydereign
EvanAgain wrote:I still don't understand why it works, but now it works!

First off, you were rotating with degrees instead of radians. Degrees are much larger in value, since a full circle is 360, while in radians it is 2pi. Because cos/sin require radians to behave normally if you give them degrees, they will rotate by really large amounts. Another problem is you wanted to rotate the entire line/shape, not just a point. If you rotated just the second point it will change the size of the line. Namely, in your previous code (assuming the other things were fixed) it would be rotating that second point around the canvas' top left pixel, without changing the first point. So naturally the line will change length.

Now, the transformation matrix always rotates around the origin. In this case, like stated above, is the top left pixel of the canvas. If you want to rotate something around a different point, you need to shift the object so that the point is now at the origin. You can do this by subtracting the rotation point from the vertices in the object. Do the rotation, and then add the rotation point back, so that it didn't actually move position.

EvanAgain wrote:but it seems that "Rad" (not sure if thats properly named) seems to control the velocity of the rotation.

Right, the reason for this is the rotation matrix will rotate it by a certain amount each time. So if you call the rotation with pi, it will rotate it 180 degrees. If you want to be able to rotate it via the degree you want, you'll have to preserve the original coordinates, so you can rotate it from that (or hold on to its current rotation, rotate it back to 0, and rotate it again).

EvanAgain wrote:I understand that it controls the amount of rotation per function call but should I be calling Update_Canvas every frame? Is their a better way of doing this? Currently, Update_Canvas is in the Canvas->Draw Actor.

This depends purely on what you want and what you are doing. Do you need to rotate it every frame? If so, you'll have to also redraw it every frame. And if you want it to rotate by some amount every frame, naturally you'll need to do the rotation computation as well.

EvanAgain wrote:Also, if I had two canvas and I was swapping them like a buffer, would that improve the visual performance? Would it make the smoother?

I don't think so. The only improvement to visual performance would be making it faster, and gE will still have to do the same amount of computation (technically a little more) if you use two canvas actors. Since we aren't dealing with threads one will still need to be erased every frame, one will still need to be drawn every frame.

Re: Help! I can't understand this code!!

PostPosted: Sun Feb 17, 2013 12:19 am
by EvanAgain
Rotating Line Code:
Code: Select all
#define PI 3.141592

struct Vector2d;

typedef struct Vector2d

{
    double x;
    double y;
}Vector2d;

struct Line;
typedef struct Line
{
    Vector2d Point1;
    Vector2d Point2;
}Line;

double Rad = 3;
Vector2d Pivot = {100,100};

Line myLine;

void FindNewVector(double *old_x, double *old_y, int rx, int ry, double theta)
{ // make sure theta is in radians when calling this, or convert within the function
    double new_x;
    double new_y;
    (*old_x)-=rx; // first subtracted
    (*old_y)-=ry;
    theta = theta * PI / 180;
 
    new_x = cos(theta) * (*old_x) - sin(theta) * (*old_y);
    new_y = sin(theta) * (*old_x) + cos(theta) * (*old_y);
 
    (*old_x) = new_x+rx; // added back
    (*old_y) = new_y+ry;
}


void RotateLine(Line *li)
{
    FindNewVector(&li->Point1.x, &li->Point1.y, Pivot.x, Pivot.y, Rad);
    FindNewVector(&li->Point2.x, &li->Point2.y, Pivot.x, Pivot.y, Rad);
}


void DrawLine(Line *li)
{
    moveto(li->Point1.x, li->Point1.y);
    lineto(li->Point2.x, li->Point2.y);
}

void Update_Canvas()
{
    erase(0,0,0,0);
 
    setpen(255,255,255,0,2);
    RotateLine(&myLine);
    DrawLine(&myLine);
 
}

void Init_Line()
{
    myLine.Point1.x =  200;
    myLine.Point1.y =  50;
    myLine.Point2.x =  200;
    myLine.Point2.y =  200;
 
    Pivot.x = (myLine.Point1.x + myLine.Point2.x) /2;
    Pivot.y = (myLine.Point1.y + myLine.Point2.y) /2;
}


I am renaming this thread, because the direction of the thread has changed.


I have a question now on 2D collision detection. I read about two different ones but can't find anything that makes sense. They keep making a call to a function CrossProduct() which my computer was failing to allow me to search google for.


Anywho, the Topic was Line Intersection. How to find out if a point is within a shape and to see if a line crosses with a line of a shape. From what I understand is that I need to find if a point is within the area of a shape or if the line intersects with the shape or if two shapes intersect. Which I am trying to figure out the formulas and algorithms for this.

Any lead on 2D collision detection?

Re: Help! I can't understand this code!!

PostPosted: Sun Feb 17, 2013 12:27 am
by skydereign
How specific do you want this collision detection to be? If you just want to tell if two shapes collide, it is pretty straight forward. Here's an explanation of the cross product/checking if lines intersect. http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect

EvanAgain wrote:Anywho, the Topic was Line Intersection. How to find out if a point is within a shape and to see if a line crosses with a line of a shape. From what I understand is that I need to find if a point is within the area of a shape or if the line intersects with the shape or if two shapes intersect. Which I am trying to figure out the formulas and algorithms for this.

The usual method to tell if a point is within a shape is a well documented problem.
http://en.wikipedia.org/wiki/Point_in_polygon
I've actually been looking into this recently for school work, and found this link quite useful. http://stackoverflow.com/questions/217578/point-in-polygon-aka-hit-test

Re: 2D: Collision, Rotation, Scale, and more IN CANVAS

PostPosted: Sun Feb 17, 2013 12:43 am
by EvanAgain
Thank you so much, Here is a link I am currently looking over: http://devmag.org.za/2009/04/13/basic-c ... 2d-part-1/

I, very much, appreciate your help with this. I don't go to school for this so it all just home learning. I will keep making more code snippets and hopefully this will become a useful thread for anyone interested in the topics.


Links:
Geometry
http://community.topcoder.com/tc?module ... =geometry2

Cross Product
http://en.wikipedia.org/wiki/Cross_product

Dot Product
http://en.wikipedia.org/wiki/Dot_product

Line Intersection
http://alienryderflex.com/intersect/

Re: 2D: Collision, Rotation, Scale, and more IN CANVAS

PostPosted: Sun Mar 10, 2013 12:17 am
by GEuser
EvanAgain wrote:Thank you so much, Here is a link I am currently looking over: http://devmag.org.za/2009/04/13/basic-c ... 2d-part-1/

I, very much, appreciate your help with this. I don't go to school for this so it all just home learning. I will keep making more code snippets and hopefully this will become a useful thread for anyone interested in the topics.


Links:
Geometry
http://community.topcoder.com/tc?module ... =geometry2

Cross Product
http://en.wikipedia.org/wiki/Cross_product

Dot Product
http://en.wikipedia.org/wiki/Dot_product

Line Intersection
http://alienryderflex.com/intersect/


Hey. thanks for the links. I was also looking into creating polygon functions but got side tracked and never went back to it. Would be interesting to see what progress you make on this. Keep us posted.