OpenGL大作业是画一个自行车,难度不高,但是代码量还是比较大的,所以放到博客上展示一下,不具备什么技术性。

全部代码放在最后,可以先看源码再看讲解。

0、准备工作

我们首先各种include

之后定义pi。因为这个程序是我之前画的一个贪吃蛇程序改的,所以画布的定义通过定义格子的数量及大小确定的,这里没有改所以就放在这了。

#define pi 3.1415926535897932
//这里是定义画布的大小,按格子划分画布,一个格子50,一行20个格子
#define gridSize 50
#define gridnum 20

然后为了方便我定义了一个点类,虽然也可以用二维数组或者结构体,不过还是习惯了定义成class。为了方便,全部public,大作业而已要什么严谨,因为OpenGL主要都是float类型,所以这里也用的float而不是double,理论上高精度转低精度问题不大,但是不想管了。

class Point
{
public:float x;float y;Point(float x, float y) {this->x = x;this->y = y;}
};

定义一个点A(1,1)的时候可以直接写

Point A=Point(1,1);

1、Bike类的结构

下面就是这次作业的主要内容了

1.0 成员变量

为了方便,我们需要先定义好这个自行车的特征点。车轮位置、车把位置、旋转过的角度等。

    bool Fill = true;                   //定义是填充还是线框,true是填充double roAngle = 0;                  //绘图的初始角度,逐渐改变roAngle可以让图像运动Point wheel1 = Point(300, 0);       //前轮中心的位置Point wheel2 = Point(-300, 0);        //后轮的中心位置Point Pedal = Point(0, 0);            //脚踏板的中心位置char mode = 'L';                   //运行速度可选low mid high

1.1 画圆

我搜索发现OpenGL是没有什么画圆的函数的,所以找到了别人的代码,稍微修改了一下。原理就是利用for循环画多边形,其中accuracy是控制圆的精度的。传入参数Point O是圆心坐标,float r是圆的半径。

没有加控制颜色的内容,所以使用时要先用修改颜色的函数,否则就是跟前面的颜色一样,也行。

void DrawCircular(Point O, float r) {int accuracy = 72;glBegin(GL_POLYGON);for (int i = 0; i < accuracy; ++i)glVertex2f(O.x + r * cos(2 * pi / accuracy * i), O.y + r * sin(2 * pi / accuracy * i));glEnd();glFlush();}

1.2 旋转点

在实现过程中发现画一个斜着的矩形比较麻烦,要输入四个点。而且自行车车轮的辐条也需要利用旋转才可以实现,所以我定义了一个将点绕另一个点旋转的函数。返回的结果是一个Point类型。

实现的功能就是将点p绕点o旋转angle°,这里用的角度制,会比较方便使用。

Point PointRotate(Point o, Point p, double angle) {angle = (angle / 180) * pi;float px = p.x - o.x;float py = p.y - o.y;float tempx = px * cos(angle) - py * sin(angle);float tempy = px * sin(angle) + py * cos(angle);return Point(o.x + tempx, o.y + tempy);}

1.3 绘制斜矩形

OpenGL提供的绘制矩形的函数只能是一个方向的,而自行车绘图里会有很多斜的矩形,所以定义了斜着绘制矩形的函数。

把斜的长方形看成一条线段,那么线段的端点就是p1和p2,width是线宽的一半。

原理就是p1p点在选段上,距离p1点width,然后将这个p1p点绕p1点旋转±90°得到两个点。同样找到p2p点,绕p2点旋转±90°,就可以得到四个点ABCD,最后调用绘制多边形,输入这四个点就可以实现了。

但是最后会出现bug,某条长边的边会出现曲线,原因未知,所以我就画两个三角形,最后看的效果还是一样的。

void DrawLine(Point p1, Point p2, float width) {float lineLength = sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));float x_p1p = p1.x + (p2.x - p1.x) * width / lineLength;float y_p1p = p1.y + (p2.y - p1.y) * width / lineLength;Point p1p = Point(x_p1p, y_p1p);float x_p2p = p2.x + (p1.x - p2.x) * width / lineLength;float y_p2p = p2.y + (p1.y - p2.y) * width / lineLength;Point p2p = Point(x_p2p, y_p2p);Point A = PointRotate(p1, p1p, 90);Point B = PointRotate(p1, p1p, -90);Point C = PointRotate(p2, p2p, -90);Point D = PointRotate(p2, p2p, 90);glBegin(GL_POLYGON);glVertex2f(D.x, D.y);glVertex2f(C.x, C.y);glVertex2f(B.x, B.y);glEnd();glBegin(GL_POLYGON);glVertex2f(A.x, A.y);glVertex2f(C.x, C.y);glVertex2f(B.x, B.y);glEnd();}

1.4 画车架

首先为了方便,把自行车的几个特征点记下来,车轮wheel1和wheel2,车座底端vertex,车座Seat,车头head,车把Handle,脚踏板旋转中心Pedal。

之后要做的就是调用 绘制斜长方形的函数DrawLine,连接这几个点就行了。

void DrawFrame() {Point Seat = Point(-150, 300);Point vertex = Point(-125, 250);glColor3f(0.0, 1.0, 0.0);DrawLine(wheel2, Pedal, 10);DrawLine(wheel2, vertex, 10);DrawLine(Pedal, Seat, 10);DrawLine(Point(Seat.x - 50, Seat.y), Point(Seat.x + 100, Seat.y), 15);Point head(200, 250);Point Handle(170, 350);DrawLine(head, vertex, 10);DrawLine(head, Pedal, 10);DrawLine(Handle, wheel1, 10);DrawLine(Point(Handle.x + 10, Handle.y), Point(Handle.x - 70, Handle.y), 10);DrawCircular(wheel1, 20);DrawCircular(wheel2, 20);DrawCircular(Pedal, 20);}

1.5 画脚踏板

设置脚踏板的旋转中心为Point O

圆环用画圆函数,画一个大圆,一个白色的小同心圆盖住即可。

脚踏杆用DrawLine函数。但是因为设计到旋转,所以这个脚踏杆的初始位置一端就是旋转中心O,另一端就是绕O旋转angle°,由于这个角度需要随时间变化,所以这个在类里设计了一个成员变量roAngle记录当前旋转到的角度就可以了。

void DrawPedal(Point O) {double angle = (roAngle - 60) * pi / 180;DrawCircular(O, 50);glColor3f(1.0, 1.0, 1.0);DrawCircular(O, 30);glColor3f(1.0f, 0.0, 0.0);double length = 120;Point p3 = Point(O.x + length * cos(angle), O.y + length * sin(angle));glColor3f(0.0f, 1.0, 0.0);DrawLine(O, p3, 10);DrawLine(Point(p3.x - 50, p3.y), Point(p3.x + 50, p3.y), 10);DrawCircular(p3, 10);}

1.6 滑轮子

和脚踏板没啥区别,还是圆和斜线,还是绕roAngle°,所以直接上代码。

轮子的中心Point O

 void DrawWheel(Point O) {glColor3f(1.0f, 0.0, 0.0);DrawCircular(O, 200);glColor3f(1.0, 1.0, 1.0);DrawCircular(O, 180);glColor3f(1.0, 0.0, 0.0);glBegin(GL_POLYGON);               float weidth = 10;float length = 200;Point p1 = Point(-1 * weidth + O.x, -1 * length + O.y);Point p2 = Point(weidth + O.x, -1 * length + O.y);Point p3 = Point(weidth + O.x, O.y);Point p4 = Point(-1 * weidth + O.x, O.y);double angle = roAngle;for (int i = 0; i < 6; i++) {Point p5 = PointRotate(O, p1, angle);Point p6 = PointRotate(O, p2, angle);Point p7 = PointRotate(O, p3, angle);Point p8 = PointRotate(O, p4, angle);glBegin(GL_POLYGON);glVertex2f(p5.x, p5.y);glVertex2f(p6.x, p6.y);glVertex2f(p7.x, p7.y);glVertex2f(p8.x, p8.y);glEnd();angle = angle + 60;}}

1.7 画自行车

画元素的函数都编完了,那剩下的就是调用就行了。开始前先clear清除一下画布。

由于有要求说可选填充或者线框,所以做一个判断,是否Fill,决定使用GL_FILL还是GL_LINE。其他的注意遮挡关系,先后画图就好。

最后glFlush刷新到画布上,清空缓存。

    void BikeDisplay() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);if (Fill){glPolygonMode(GL_FRONT, GL_FILL);glPolygonMode(GL_BACK, GL_FILL);}else {glPolygonMode(GL_FRONT, GL_LINE);glPolygonMode(GL_BACK, GL_LINE);}glFrontFace(GL_CW);DrawWheel(wheel1);DrawWheel(wheel2);DrawPedal(Pedal);DrawFrame();glFlush();glutSwapBuffers();}

1.8 旋转函数

很简单就是让旋转过的角度roAngle增加就行,不过需要根据运行速度低中高,分别设置增量。直接用Switch分支结构就行。

    void Rotate() {switch (mode){case 'L': {roAngle = roAngle - 5; break; }case 'M': {roAngle = roAngle - 10; break; }case 'H': {roAngle = roAngle - 25; break; }default:break;}}

2、子菜单定义

下面的代码一次添加到主函数里就行

先定义子菜单1,速度菜单

glutCreateMenu(speed_menu);是调用speed_menu函数,

传入的参数就是glutAddMenuEntry("低速", 2);中的这个2。每个标签分别对应一个传入参数。

所以点击子菜单中的"低速",相当于运行speed_menu(2)。

 int sub_menu1 = glutCreateMenu(speed_menu);glutAddMenuEntry("低速", 2);glutAddMenuEntry("中速", 3);glutAddMenuEntry("高速", 4);

定义子菜单2,线框、填充

 int sub_menu2 = glutCreateMenu(mode_menu);glutAddMenuEntry("填充", 5);glutAddMenuEntry("线框", 6);

定义主菜单

 //定义主菜单,并将前面的两个子菜单填入glutCreateMenu(main_menu);glutAddSubMenu("速度", sub_menu1);glutAddSubMenu("模式", sub_menu2);//设置鼠标右键为开启菜单的开关glutAttachMenu(GLUT_RIGHT_BUTTON);

回调函数

写在main前面

void main_menu(int id)
{
}void speed_menu(int id) {switch (id){case 2: bike.mode = 'L';break;case 3: bike.mode = 'M';break;case 4: bike.mode = 'H';break;}
}void mode_menu(int id) {switch (id){case 5:bike.Fill = true;break;case 6:bike.Fill = false;break;}
}

3、OpenGL要求使用的函数

初始化函数

确定初始化画布的颜色、大小、窗口位置、显示范围。照抄就行

void init() {glClearColor(1.0, 1.0, 1.0, 1.0);glColor3f(1.0f, 0.0f, 0.0f);               gluOrtho2D(0.0, (gridnum + 2) * gridSize / 2, 0.0, (gridnum + 2) * gridSize / 2);
}

改变窗口尺寸时的函数

void changSize(GLint w, GLint h) {GLfloat ratio;GLfloat coordinatesize = 1000.0f;if ((w == 0) || (h == 0))return;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();ratio = (GLfloat)w / (GLfloat)h;if (w < h)glOrtho(-coordinatesize, coordinatesize, -coordinatesize / ratio, coordinatesize / ratio, -coordinatesize, coordinatesize);elseglOrtho(-coordinatesize * ratio, coordinatesize * ratio, -coordinatesize, coordinatesize, -coordinatesize, coordinatesize);glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}

初始化一个自行车对象

Bike bike;

显示函数

void MyDisplay() {bike.Rotate();bike.BikeDisplay();
}

定时函数

负责100ms之后再次显示,里面嵌套一次定时函数,就可以实现一直运动的效果。

void TimerFunc(int value)
{glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);
}

主函数

依次调用前面定义好的函数就行,没说到的代码基本是OpenGL项目都要写的代码。

int main(int argc, char** argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);  glutInitWindowPosition(200, 50);                glutInitWindowSize(gridnum * gridSize, gridnum * gridSize);glutCreateWindow("Point");                     init();                                         glutDisplayFunc(MyDisplay);                     glutTimerFunc(100, TimerFunc, 1);glutReshapeFunc(changSize);    int sub_menu1 = glutCreateMenu(speed_menu);glutAddMenuEntry("低速", 2);glutAddMenuEntry("中速", 3);glutAddMenuEntry("高速", 4);int sub_menu2 = glutCreateMenu(mode_menu);glutAddMenuEntry("填充", 5);glutAddMenuEntry("线框", 6);glutCreateMenu(main_menu);glutAddSubMenu("速度", sub_menu1);glutAddSubMenu("模式", sub_menu2);glutAttachMenu(GLUT_RIGHT_BUTTON);glutMainLoop();return 0;
}

4、全部代码

//这里的include要配置一下不然找不到glut.h,可以参考其他博客
#include <GL/glut.h>
#include <iostream>
#include <stdlib.h>
#include <thread>
#include <math.h>
using namespace std;//这里进行了一些宏定义,pi为圆周率已经定义到double的极限了
#define pi 3.1415926535897932
//这里是定义画布的大小,按格子划分画布,一个格子50,一行20个格子
#define gridSize 50
#define gridnum 20//定义一个点类,方便后续操作,二维数组也行,不过我习惯了定义成类
class Point
{
public:float x;float y;Point(float x, float y) {this->x = x;this->y = y;}
};//定义画自行车的类
class Bike
{
public:bool Fill = true;                   //定义是填充还是线框,true是填充double roAngle = 0;                  //绘图的初始角度,逐渐改变roAngle可以让图像运动Point wheel1 = Point(300, 0);       //前轮中心的位置Point wheel2 = Point(-300, 0);        //后轮的中心位置Point Pedal = Point(0, 0);            //脚踏板的中心位置char mode = 'L';                   //运动速度,L、M、H分别是低中高速//绘图函数,将整个自行车画出来void BikeDisplay() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);if (Fill){glPolygonMode(GL_FRONT, GL_FILL);glPolygonMode(GL_BACK, GL_FILL);}else {glPolygonMode(GL_FRONT, GL_LINE);glPolygonMode(GL_BACK, GL_LINE);}glFrontFace(GL_CW);DrawWheel(wheel1);DrawWheel(wheel2);DrawPedal(Pedal);DrawFrame();glFlush();glutSwapBuffers();}//逐渐改变绘制图形的初始角度,让自行车轮及脚踏板旋转的函数void Rotate() {switch (mode){case 'L': {roAngle = roAngle - 5; break; }case 'M': {roAngle = roAngle - 10; break; }case 'H': {roAngle = roAngle - 25; break; }default:break;}}private://定义一个画圆的函数,圆心点O,半径为rvoid DrawCircular(Point O, float r) {int accuracy = 72;glBegin(GL_POLYGON);for (int i = 0; i < accuracy; ++i)glVertex2f(O.x + r * cos(2 * pi / accuracy * i), O.y + r * sin(2 * pi / accuracy * i));glEnd();glFlush();}//将P点绕o点旋转angle度Point PointRotate(Point o, Point p, double angle) {angle = (angle / 180) * pi;float px = p.x - o.x;float py = p.y - o.y;float tempx = px * cos(angle) - py * sin(angle);float tempy = px * sin(angle) + py * cos(angle);return Point(o.x + tempx, o.y + tempy);}//画一条“线”,是一个斜着的矩形,短边中心点为p1和p2,长方形的宽度为width//直接绘制斜的矩形会出长边变曲线的问题,所以分成两个三角形画void DrawLine(Point p1, Point p2, float width) {float lineLength = sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));float x_p1p = p1.x + (p2.x - p1.x) * width / lineLength;float y_p1p = p1.y + (p2.y - p1.y) * width / lineLength;Point p1p = Point(x_p1p, y_p1p);float x_p2p = p2.x + (p1.x - p2.x) * width / lineLength;float y_p2p = p2.y + (p1.y - p2.y) * width / lineLength;Point p2p = Point(x_p2p, y_p2p);Point A = PointRotate(p1, p1p, 90);Point B = PointRotate(p1, p1p, -90);Point C = PointRotate(p2, p2p, -90);Point D = PointRotate(p2, p2p, 90);glBegin(GL_POLYGON);glVertex2f(D.x, D.y);glVertex2f(C.x, C.y);glVertex2f(B.x, B.y);glEnd();glBegin(GL_POLYGON);glVertex2f(A.x, A.y);glVertex2f(C.x, C.y);glVertex2f(B.x, B.y);glEnd();}//利用定义好的DrawLine函数,绘制自行车的车架void DrawFrame() {Point Seat = Point(-150, 300);Point vertex = Point(-125, 250);glColor3f(0.0, 1.0, 0.0);DrawLine(wheel2, Pedal, 10);DrawLine(wheel2, vertex, 10);DrawLine(Pedal, Seat, 10);DrawLine(Point(Seat.x - 50, Seat.y), Point(Seat.x + 100, Seat.y), 15);Point head(200, 250);Point Handle(170, 350);DrawLine(head, vertex, 10);DrawLine(head, Pedal, 10);DrawLine(Handle, wheel1, 10);DrawLine(Point(Handle.x + 10, Handle.y), Point(Handle.x - 70, Handle.y), 10);DrawCircular(wheel1, 20);DrawCircular(wheel2, 20);DrawCircular(Pedal, 20);}//利用DrawCircular和DrawLine函数,绘制脚踏板及轴void DrawPedal(Point O) {double angle = (roAngle - 60) * pi / 180;DrawCircular(O, 50);glColor3f(1.0, 1.0, 1.0);DrawCircular(O, 30);glColor3f(1.0f, 0.0, 0.0);double length = 120;Point p3 = Point(O.x + length * cos(angle), O.y + length * sin(angle));glColor3f(0.0f, 1.0, 0.0);DrawLine(O, p3, 10);DrawLine(Point(p3.x - 50, p3.y), Point(p3.x + 50, p3.y), 10);DrawCircular(p3, 10);}//利用DrawCircular、PointRotate函数,绘制车轮void DrawWheel(Point O) {glColor3f(1.0f, 0.0, 0.0);DrawCircular(O, 200);glColor3f(1.0, 1.0, 1.0);DrawCircular(O, 180);glColor3f(1.0, 0.0, 0.0);glBegin(GL_POLYGON);               float weidth = 10;float length = 200;Point p1 = Point(-1 * weidth + O.x, -1 * length + O.y);Point p2 = Point(weidth + O.x, -1 * length + O.y);Point p3 = Point(weidth + O.x, O.y);Point p4 = Point(-1 * weidth + O.x, O.y);double angle = roAngle;for (int i = 0; i < 6; i++) {Point p5 = PointRotate(O, p1, angle);Point p6 = PointRotate(O, p2, angle);Point p7 = PointRotate(O, p3, angle);Point p8 = PointRotate(O, p4, angle);glBegin(GL_POLYGON);glVertex2f(p5.x, p5.y);glVertex2f(p6.x, p6.y);glVertex2f(p7.x, p7.y);glVertex2f(p8.x, p8.y);glEnd();angle = angle + 60;}}
};//初始化函数
void init() {glClearColor(1.0, 1.0, 1.0, 1.0);glColor3f(1.0f, 0.0f, 0.0f);              gluOrtho2D(0.0, (gridnum + 2) * gridSize / 2, 0.0, (gridnum + 2) * gridSize / 2);
}//改变尺寸时的函数
void changSize(GLint w, GLint h) {GLfloat ratio;GLfloat coordinatesize = 1000.0f;if ((w == 0) || (h == 0))return;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();ratio = (GLfloat)w / (GLfloat)h;if (w < h)glOrtho(-coordinatesize, coordinatesize, -coordinatesize / ratio, coordinatesize / ratio, -coordinatesize, coordinatesize);elseglOrtho(-coordinatesize * ratio, coordinatesize * ratio, -coordinatesize, coordinatesize, -coordinatesize, coordinatesize);glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}//初始化全局变量bike
Bike bike;//主函数的display回调函数,旋转车轮并让bike画图
void MyDisplay() {bike.Rotate();bike.BikeDisplay();
}//设置定时的回调函数,调用MyDisplay,并再次定时完成循环绘图
void TimerFunc(int value)
{glutPostRedisplay();glutTimerFunc(100, TimerFunc, 1);
}//主菜单的回调函数,主菜单没有独立子项,所以什么也不用做,不报错就行
void main_menu(int id)
{
}//调节速度的子菜单,id:2,3,4分别代表低中高速度
void speed_menu(int id) {switch (id){case 2: bike.mode = 'L';break;case 3: bike.mode = 'M';break;case 4: bike.mode = 'H';break;}
}//调节显示模式的子菜单,id:5,6分别代表填充与线框
void mode_menu(int id) {switch (id){case 5:bike.Fill = true;break;case 6:bike.Fill = false;break;}
}int main(int argc, char** argv) {//常规的初始化、定义窗口大小及位置的步骤glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   glutInitWindowPosition(200, 50);                glutInitWindowSize(gridnum * gridSize, gridnum * gridSize);glutCreateWindow("Point");                     init();                                         glutDisplayFunc(MyDisplay);                     glutTimerFunc(100, TimerFunc, 1);glutReshapeFunc(changSize);    //定义速度子菜单及内容int sub_menu1 = glutCreateMenu(speed_menu);glutAddMenuEntry("低速", 2);glutAddMenuEntry("中速", 3);glutAddMenuEntry("高速", 4);//定义模式子菜单及内容int sub_menu2 = glutCreateMenu(mode_menu);glutAddMenuEntry("填充", 5);glutAddMenuEntry("线框", 6);//定义主菜单,并将前面的两个子菜单填入glutCreateMenu(main_menu);glutAddSubMenu("速度", sub_menu1);glutAddSubMenu("模式", sub_menu2);//设置鼠标右键为开启菜单的开关glutAttachMenu(GLUT_RIGHT_BUTTON);glutMainLoop();return 0;
}

OpenGL画自行车+菜单设置(附源码)相关推荐

  1. Silverlight4中右键菜单实现-附源码下载

    在发布Silverlight4 Beta版本和RC时 增加不少新的特性和控件. 类似在WinForm实现右键菜单ContentMenu功能. 在Silverlight 4中也有所体现. 当初在Silv ...

  2. Winforn中实现ZedGraph自定义添加右键菜单项(附源码下载)

    场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...

  3. 【C#+SQL Server+打印组件】实现电商快递单打印系统 三:主窗体中的快捷菜单(附源码和资源)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.快捷单设置的快捷菜单 打开主窗体AppForm的设计界面,双击主窗体的标题栏,切换到主窗体的代码页,在代码页的公共变量或方法的编写区,创建CommCl ...

  4. Python的turtle模块画爱心箭(附源码)

    Python的turtle模块画爱心箭源码 import turtle as t t.hideturtle() t.speed(100) def f(a,b):#画箭,a,b为箭尖坐标t.penup( ...

  5. 值得学习的单片机菜单框架(附源码)

    点击上方"小麦大叔",选择"置顶/星标公众号" 福利干货,第一时间送达 大家好,我是小麦,以前用单片机做用户交互的菜单的时候,都比较痛苦,如何写一个复用性高,方 ...

  6. Android Studio App开发之通知渠道NotificationChannel及给华为、小米手机桌面应用添加消息数量角标实战(包括消息重要级别的设置 附源码)

    需要全部源码或运行有问题请点赞关注收藏后评论区留言~~~ 一.通知渠道NtoificationChannel 为了分清消息通知的轻重缓急,Android8.0新增了通知渠道,并且必须指定通知渠道才能正 ...

  7. 用opengl画一个3D机器人 完整源码 直接使用

    机器人代码: 1.copy就可以运行,前提是要配置好opengl的环境. 2.最后有使用说明. // first.cpp : Defines the entry point for the conso ...

  8. Python画蔡徐坤 附源码

    首先看效果图 复制粘贴即可运行 from turtle import * from math import *# 高级椭圆参数方程(颜色),sita为逆时针旋转角度 def ty_c(x, y, si ...

  9. python程序员专用壁纸_程序员炫技必备:用Python生成马赛克画!(文末附源码)...

    原标题:程序员炫技必备:用Python生成马赛克画!(文末附源码) 源 | Python与数据分析文 | 强哥 大家知道马赛克画是什么吗?不是动作片里的马赛克哦~~ 马赛克画是一张由小图拼成的大图,本 ...

最新文章

  1. javaScript 工作必知(三) String .的方法从何而来?
  2. 数据库死锁及解决方法
  3. v-if 和 v-else-if 和 v-else 的使用
  4. Leetcode215数组中第k大的数-最小堆
  5. 判断当前时间是否在某个时间范围内
  6. linux 下简单的ftp客户端程序
  7. SAP JAM的推荐菜单,书签和日历功能
  8. kettle同步数据中文乱码问题解决
  9. stack示例_C.示例中的Stack.CopyTo()方法
  10. python基础入门(2)
  11. Python gevent高并发(限制最大并发数、协程池)
  12. linux tcp 服务器 c,Linux网络编程篇之Tcp协议介绍, C/S通信及聊天室实现
  13. pom模块依赖关系梳理
  14. [Java] 蓝桥杯ADV-184 算法提高 素数求和
  15. 基于Redis的微博计算好友关系
  16. ERP软件管理持续升级 抢占产业先机
  17. 虚拟机安装BackTrack 5 的教程详解!
  18. 小demo,点石成金
  19. 微信公众号推送功能代码及详解
  20. 前端程序员拿到新电脑第一天,该做些什么?

热门文章

  1. VMware,Inc. (Virtual Machine ware)
  2. 计算机网络的常见面试题
  3. Kafka之Controller(Broker的领导者)
  4. 诺基亚Symbian算不算智能手机?
  5. Z 字形变换(Python)
  6. 蔬菜(vegetable)
  7. bootstrap图片上传
  8. 404未找到是什么意思_常见的web错误404你知道是什么意思吗?
  9. 文件加密都有哪些方法?
  10. split函数的用法——java