- 目前进度:多边形的平移、旋转、缩放
- 实现线段、圆和多边形的基本2D几何变换
- 平移
- 旋转(含基准点)
- 缩放(含基准点)
- Visual Studio 2019
- Windows 10
对于多边形的各顶点添加一段平移距离,
{
x
′
=
x
+
t
x
y
′
=
y
+
t
y
begin{cases} x'=x+tx\ y'=y+ty end{cases}
{x′=x+txy′=y+ty
记原多边形顶点为
P
P
P,平移后的多边形顶点为
P
′
P'
P′,平移向量为
T
T
T,则
P
=
[
x
y
]
,
P
′
=
[
x
′
y
′
]
,
T
=
[
t
x
t
y
]
P=left[begin{matrix} x\y end{matrix}right],P'=left[begin{matrix} x'\y' end{matrix}right],T=left[begin{matrix} tx\ty end{matrix}right]
P=[xy],P′=[x′y′],T=[txty]
P ′ = P + T P'=P+T P′=P+T
旋转对于多边形的各顶点,绕基准点
(
x
r
,
y
r
)
(x_r,y_r)
(xr,yr)逆时针旋转角度
θ
theta
θ,
{
x
′
−
x
r
=
(
x
−
x
r
)
c
o
s
θ
−
(
y
−
y
r
)
s
i
n
θ
y
′
−
y
r
=
(
x
−
x
r
)
s
i
n
θ
+
(
y
−
y
r
)
c
o
s
θ
begin{cases} x'-x_r=(x-x_r){rm cos}theta-(y-y_r){rm sin}theta \ y'-y_r=(x-x_r){rm sin}theta+(y-y_r){rm cos}theta end{cases}
{x′−xr=(x−xr)cosθ−(y−yr)sinθy′−yr=(x−xr)sinθ+(y−yr)cosθ
P ′ = R ⋅ P , R = [ c o s θ − s i n θ s i n θ c o s θ ] P'=Rcdot P,quad R= left[ begin{matrix} {rm cos}theta & -{rm sin}theta \ {rm sin}theta & {rm cos}theta end{matrix} right] P′=R⋅P,R=[cosθsinθ−sinθcosθ]
缩放对于多边形的各顶点,保持基准点不动进行缩放,其中
s
x
,
s
y
s_x,s_y
sx,sy为
x
,
y
x,y
x,y方向的缩放比例。
{
x
′
=
x
⋅
s
x
y
′
=
y
⋅
s
y
begin{cases} x'=xcdot s_x \ y'=ycdot s_y end{cases}
{x′=x⋅sxy′=y⋅sy
P ′ = S ⋅ P , S = [ s x 0 0 s y ] P'=Scdot P,quad S= left[ begin{matrix} s_x & 0 \ 0 & s_y end{matrix} right] P′=S⋅P,S=[sx00sy]
四、实验结果 五、附录#include#include #include #define PI acos(-1) using namespace std; struct wcPt2D { GLfloat x, y; }; wcPt2D verts[3]; wcPt2D pivPt; void getVerts(wcPt2D* verts) { verts[0].x = -0.7; verts[0].y = 0.5; verts[1].x = -0.5; verts[1].y = 0.7; verts[2].x = -0.6; verts[2].y = 0.7; } void drawOriginalPolygon(wcPt2D* verts, GLint nVerts) { glBegin(GL_POLYGON); for (int k = 0; k < nVerts; k++) { glVertex2f(verts[k].x, verts[k].y); } glEnd(); } void translatePolygon(wcPt2D* verts, GLint nVerts, GLfloat tx, GLfloat ty) // (tx,ty)为平移向量 { wcPt2D* tmp = new wcPt2D[nVerts]; for (int k = 0; k < nVerts; k++) { tmp[k].x = verts[k].x + tx; tmp[k].y = verts[k].y + ty; } glBegin(GL_POLYGON); for (int k = 0; k < nVerts; k++) { glVertex2f(tmp[k].x, tmp[k].y); } glEnd(); } void rotatePolygon(wcPt2D* verts, GLint nVerts, wcPt2D pivPt, GLdouble theta) // pivPt:基准点;theta:逆时针旋转角度 { float xr = pivPt.x; float yr = pivPt.y; wcPt2D* tmp = new wcPt2D[nVerts]; for (int k = 0; k < nVerts; k++) { tmp[k].x = xr + (verts[k].x - xr) * cos(theta) - (verts[k].y - yr) * sin(theta); tmp[k].y = yr + (verts[k].x - xr) * sin(theta) + (verts[k].y - yr) * cos(theta); } glBegin(GL_POLYGON); for (int k = 0; k < nVerts; k++) { glVertex2f(tmp[k].x, tmp[k].y); } glEnd(); } void scalePolygon(wcPt2D* verts, GLint nVerts, wcPt2D pivPt, GLfloat sx, GLfloat sy) // pivPt:基准点 { float xr = pivPt.x; float yr = pivPt.y; wcPt2D* tmp = new wcPt2D[nVerts]; for (int k = 0; k < nVerts; k++) { tmp[k].x = sx * verts[k].x + (1 - sx) * xr; tmp[k].y = sy * verts[k].y + (1 - sy) * yr; } glBegin(GL_POLYGON); for (int k = 0; k < nVerts; k++) { glVertex2f(tmp[k].x, tmp[k].y); } glEnd(); } int main(void) { GLFWwindow* window; if (!glfwInit()) return -1; window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); if (glewInit() != GLEW_OK) cout << "Error!" << endl; // cout << glGetString(GL_VERSION) << endl; getVerts(verts); cout << verts[1].x << endl; while (!glfwWindowShouldClose(window)) { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); drawOriginalPolygon(verts,3); translatePolygon(verts, 3, 0.5f, 0.0f); pivPt.x = 0.0f; pivPt.y = 0.0f; //pivPt = verts[0]; rotatePolygon(verts, 3, pivPt, PI / 3); scalePolygon(verts, 3, pivPt, 0.5f, 0.5f); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)