We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I searched to find an approach and wrestled with this code. High School geometry long forgotten. My goal was to use the mouse wheel to rotate the polygon. Below is the code that includes both sin() and cos() as I was working through the details. My hope is that others will find this useful.
(* Edited to include CenterDiagram())
/*
r = sqrt(x**2+y**2)
cos(Θ) = x/r
sin(Θ) = y/r
x= cos(Θ)*r
y= sin(Θ)*r
. |
. |
. MINUSPLUS | PLUSPLUS
. 180 - degrees(asin(y/r)) | degrees(asin(y/r))
. degrees(acos(x/r)) | degrees(acos(x/r))
. |
. |
-----------------------------+------------------------
. |
. |
. MINUSMINUS | PLUSMINUS
. 180 - degrees(asin(y/r)) | 360 + degrees(asin(y/r))
. 360 - degrees(acos(x/r)) | 360 - degrees(acos(x/r))
*/
static final float ROTATION_INCREMENT = 5f;
static final int XYQUAD_PLUSPLUS = 1;
static final int XYQUAD_MINUSPLUS = 2;
static final int XYQUAD_MINUSMINUS = 3;
static final int XYQUAD_PLUSMINUS = 4;
void wheelRotate(int incr)
{
int xOffset = -width/2;
int yOffset = -height/2;
noLoop();
centerDiagram();
//transform
for (int i = 0; i< verts.size (); i++)
{
Point p = verts.get(i);
p.x += xOffset;
p.y += yOffset;
}
// rotate
for (int i = 0; i< verts.size (); i++)
{
float x;
float y;
float r;
float sTheta = 0;
float cTheta = 0;
float theta;
float radians;
int mode;
Point p = verts.get(i);
x = p.x;
y = p.y;
mode = quadrant(x, y);
r = sqrt(pow(x, 2)+pow(y, 2));
switch(mode)
{
case XYQUAD_PLUSPLUS:
println("XYQUAD_PLUSPLUS");
sTheta = degrees(asin(y/r));
cTheta = degrees(acos(x/r));
break;
case XYQUAD_MINUSPLUS:
println("XYQUAD_MINUSPLUS");
sTheta = 180 - degrees(asin(y/r));
cTheta = degrees(acos(x/r));
break;
case XYQUAD_MINUSMINUS:
println("XYQUAD_MINUSMINUS");
sTheta = 180 - degrees(asin(y/r));
cTheta = 360 - degrees(acos(x/r));
break;
case XYQUAD_PLUSMINUS:
println("XYQUAD_PLUSMINUS");
sTheta = 360 + degrees(asin(y/r));
cTheta = 360 - degrees(acos(x/r));
break;
}
theta = sTheta + (incr * ROTATION_INCREMENT);
if (theta > 360)
{
theta -= 360;
} else if (theta < 0)
{
theta += 360;
}
radians = radians(theta);
println("cTheta="+cTheta+" sTheta="+sTheta);
print(i+" theta="+theta+" x="+x+" y="+y+" r="+r);
println(" sin("+y+"/"+r+")="+sin(y/r)+" asin="+degrees(asin(y/r)));
p.x = (int)round((cos(radians)*r));
p.y = (int)round((sin(radians)*r));
}
// re-transform
for (int i = 0; i< verts.size (); i++)
{
Point p = verts.get(i);
p.x -= xOffset;
p.y -= yOffset;
}
centerDiagram();
loop();
}
int quadrant(float x, float y)
{
if (x>0)
{
if (y>0)
{
return XYQUAD_PLUSPLUS;
} else
{
return XYQUAD_PLUSMINUS;
}
} else if (y > 0)
{
return XYQUAD_MINUSPLUS;
} else
{
return XYQUAD_MINUSMINUS;
}
}
void centerDiagram()
{
int minX = width;
int maxX = 0;
int minY = height;
int maxY = 0;
int xOffset = 0;
int yOffset = 0;
for (int i = 0; i<verts.size (); i++)
{
Point p = verts.get(i);
xOffset += width/2 - p.x;
yOffset += height/2 - p.y;
}
xOffset /= verts.size();
yOffset /= verts.size();
for (int i = 0; i<verts.size (); i++)
{
Point p = verts.get(i);
p.x = p.x + xOffset;
p.y = p.y + yOffset;
}
}
Comments
"My hope is that others will find this useful."
Then, that's not a question? The How To category is to ask questions how to make something, not to give solutions. The name of the category can be ambiguous, but the category descriptions should make it clear.
So I moved the topic to Share your Work. And changed the topic type to Discussion instead of Question. Thanks for sharing.
isn't this just the standard 2d rotation matrix but more complicated? there's no need to convert the input points to polar co-ords and back again, just multiply each point by the relevant matrix where theta is the increment.
http://en.wikipedia.org/wiki/Rotation_matrix
Bug: Cannot find anything named "CENTER_BY_AVE_XY"! [..]
GoToLoop, I edited the post and included centerDiagram().
koogs, maybe a standard rotation matrix would do the trick. My early attempts at using
failed. However that could have been a radians vs. degrees issue. I worked through the details of sin(), asin() and radians() and degrees() and then derived the solution above.
GoToLoop, I edited the post and included centerDiagram().
koogs, maybe a standard rotation matrix would do the trick. My early attempts at using x' = x \cos \theta - y \sin \theta\,, y' = x \sin \theta + y \cos \theta\,.
failed. However that could have been a radians vs. degrees issue. I worked through the details and derived a solution
The code has been improved, and uses floats instead of ints, resulting is much more accurate rotation.
The improved code is in Why does Draw() flicker when using noLoop() ... loop() in the "Here is the well behaved code:" comment. It also includes zoom.