转载自:国庆节,我们用代码来画个国旗~ - 知乎 (zhihu.com)
如果你刚好闲的无聊,想想以前每次放假,本来放假前想好出去干啥干啥的,最后都是窝在家里敲代码了。可能很多人还是如此,那么怎样给这一天的代码的添上一点色彩?为何不做点有意思的东西?Use your CODE!
恰巧是国庆,那就让我们以一种不同的方式来庆祝她。庆祝祖国的67岁生日。让我们用不同的语言来编织我们的五星红旗……
第一个:HTML + JavaScript
代码(测试通过):
运行效果截图:
第二个:Java
代码(测试通过):
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
public class NationalFlag extends JFrame {
private int width = 288,height = width/3*2;
private double maxR = 0.15, minR = 0.05;
private double maxX = 0.50, maxY = 0.50;
private double[] minX = {0.75, 0.85, 0.85, 0.75};
private double[] minY = {0.35, 0.45, 0.60, 0.70};
public NationalFlag() {
setTitle("国旗 - by fants(铂金小鸟)");
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void paint(java.awt.Graphics graphics) {
super.paint(graphics);
java.awt.Graphics2D g = (java.awt.Graphics2D)graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//棋面
g.setColor(java.awt.Color.red);
g.fillRect(50, 50, width, height);
g.setColor(java.awt.Color.yellow);
//画大星星
double ox = height*maxX, oy = height*maxY;
g.fill(createPentacle(ox,oy,height*maxR,-Math.PI/2));
//画小星星
for(int idx =0;idx < 4;idx ++){
double sx = minX[idx]*height, sy = minY[idx]*height;
double theta = Math.atan2(oy-sy,ox-sx);
g.fill(createPentacle(sx,sy,height*minR,theta));
}
}
/**
* 创建一个五角星形状. 该五角星的中心坐标为(sx,sy),中心到顶点的距离为radius,其中某个顶点与中心的连线的偏移角度为theta(弧度)
*
* @return pentacle 一个☆
*/
public static java.awt.Shape createPentacle(double sx, double sy, double radius,double theta) {
final double arc = Math.PI / 5;
final double rad = Math.sin(Math.PI / 10) / Math.sin(3 * Math.PI / 10);
GeneralPath path = new GeneralPath();
path.moveTo(1, 0);
for (int idx = 0; idx < 5; idx++) {
path.lineTo(rad * Math.cos((1 + 2 * idx) * arc),rad * Math.sin((1 + 2 * idx) * arc));
path.lineTo(Math.cos(2 * (idx + 1) * arc),Math.sin(2 * (idx + 1) * arc));
}
path.closePath();
AffineTransform atf = AffineTransform.getScaleInstance(radius, radius);
atf.translate(sx / radius, sy / radius);
atf.rotate(theta);
return atf.createTransformedShape(path);
}
public static void main(String[] args) {
NationalFlag flag = new NationalFlag();
flag.setBounds(100, 100, 400, 400);
flag.setVisible(true);
}
}
运行效果截图:
第三个:Python(版本是2.7)
代码(测试通过):
#coding=utf-8
'''
Created on 2014-11-17
@author: Neo
'''
import turtle
import math
def draw_polygon(aTurtle, size=50, n=3):
''' 绘制正多边形
args:
aTurtle: turtle对象实例
size: int类型,正多边形的边长
n: int类型,是几边形
'''
for i in xrange(n):
aTurtle.forward(size)
aTurtle.left(360.0/n)
def draw_n_angle(aTurtle, size=50, num=5, color=None):
''' 绘制正n角形,默认为黄色
args:
aTurtle: turtle对象实例
size: int类型,正多角形的边长
n: int类型,是几角形
color: str, 图形颜色,默认不填色
'''
if color:
aTurtle.begin_fill()
aTurtle.fillcolor(color)
for i in xrange(num):
aTurtle.forward(size)
aTurtle.left(360.0/num)
aTurtle.forward(size)
aTurtle.right(2*360.0/num)
if color:
aTurtle.end_fill()
def draw_5_angle(aTurtle=None, start_pos=(0,0), end_pos=(0,10), radius=100, color=None):
''' 根据起始位置、结束位置和外接圆半径画五角星
args:
aTurtle: turtle对象实例
start_pos: int的二元tuple,要画的五角星的外接圆圆心
end_pos: int的二元tuple,圆心指向的位置坐标点
radius: 五角星外接圆半径
color: str, 图形颜色,默认不填色
'''
aTurtle = aTurtle or turtle.Turtle()
size = radius * math.sin(math.pi/5)/math.sin(math.pi*2/5)
aTurtle.left(math.degrees(math.atan2(end_pos[1]-start_pos[1], end_pos[0]-start_pos[0])))
aTurtle.penup()
aTurtle.goto(start_pos)
aTurtle.fd(radius)
aTurtle.pendown()
aTurtle.right(math.degrees(math.pi*9/10))
draw_n_angle(aTurtle, size, 5, color)
def draw_5_star_flag(times=20.0):
''' 绘制五星红旗
args:
times: 五星红旗的规格为30*20, times为倍数,默认大小为10倍, 即300*200
'''
width, height = 30*times, 20*times
# 初始化屏幕和海龟
window = turtle.Screen()
aTurtle = turtle.Turtle()
aTurtle.hideturtle()
aTurtle.speed(10)
# 画红旗
aTurtle.penup()
aTurtle.goto(-width/2, height/2)
aTurtle.pendown()
aTurtle.begin_fill()
aTurtle.fillcolor('red')
aTurtle.fd(width)
aTurtle.right(90)
aTurtle.fd(height)
aTurtle.right(90)
aTurtle.fd(width)
aTurtle.right(90)
aTurtle.fd(height)
aTurtle.right(90)
aTurtle.end_fill()
# 画大星星
draw_5_angle(aTurtle, start_pos=(-10*times, 5*times), end_pos=(-10*times, 8*times), radius=3*times, color='yellow')
# 画四个小星星
stars_start_pos = [(-5, 8), (-3, 6), (-3, 3), (-5, 1)]
for pos in stars_start_pos:
draw_5_angle(aTurtle, start_pos=(pos[0]*times, pos[1]*times), end_pos=(-10*times, 5*times), radius=1*times, color='yellow')
# 点击关闭窗口
window.exitonclick()
if __name__ == '__main__':
draw_5_star_flag()
运行效果截图:
第四个:R
代码(没有测试):
star<-function(posXY,size=1,theta=0,color="yellow")
{
alpha<-2*pi/5
R<-size
r<-sin(pi/10)*R/sin(7*pi/10)
pointpos<-matrix(0,nrow=10,ncol=2)
Beta<-(pi/10+theta)+(0:4)*alpha
pointpos[seq(1,9,2),]<-cbind(cos(Beta)*R+posXY[1],sin(Beta)*R+posXY[2])
Beta<-(3*pi/10+theta)+(0:4)*alpha
pointpos[seq(2,10,2),]<-cbind(cos(Beta)*r+posXY[1],sin(Beta)*r+posXY[2])
polygon(pointpos,col=color,border=color)
}
#计算小五角星旋转角度的函数
rotTheta<-function(posxy,posXY)
{
atan((posXY[2]-posxy[2])/(posXY[1]-posxy[1]))+pi/2
}
#常量设置
width<-3
height<-2*width/3
d<-width/30
yshift<-height/2
#国旗的坐标
Flag<-cbind(c(0,width,width,0),c(0,0,height,height))
#大五角星坐标
posXY<-c(5*d,yshift+5*d)
#小五角星坐标
posxy<-matrix(c(10,8,12,6,12,3,10,1),ncol=2,byrow=T)*d+matrix(c(0,yshift),nrow=4,ncol=2,byrow=T)
#小五角星旋转角度
rottheta<-rep(0,nrow(posxy))
rottheta<-apply(posxy,1,rotTheta,posXY)
#画红色的国旗底面
plot(Flag,type="n",col="red",axes=F,xlim=c(0,width),ylim=c(0,height),xlab="",ylab="",main="People's Republic of China",asp=1)
polygon(Flag,density=NULL,col="red",border="red")
#画出大五角星
star(posXY,size=3*height/20,theta=0,color="yellow")
#画出四颗小星
for(i in 1:nrow(posxy))
{
star(posxy[i,],size=height/20,theta=rottheta[i],color="yellow")
}
运行效果截图: