国庆节,我们用代码来画个国旗~

转载自:国庆节,我们用代码来画个国旗~ - 知乎 (zhihu.com)

如果你刚好闲的无聊,想想以前每次放假,本来放假前想好出去干啥干啥的,最后都是窝在家里敲代码了。可能很多人还是如此,那么怎样给这一天的代码的添上一点色彩?为何不做点有意思的东西?Use your CODE!

恰巧是国庆,那就让我们以一种不同的方式来庆祝她。庆祝祖国的67岁生日。让我们用不同的语言来编织我们的五星红旗……

第一个:HTML + JavaScript

代码(测试通过):

<html>
<head>
<script>
var col=new Array("red","brown");
var ticker=0;
var step=0;
function drawBackground(){
var g=document.getElementById("background").getContext("2d");
var grd=g.createLinearGradient(-560+ticker, 0, 1400+ticker,0);
for (var i=0; i<10; i++)
grd.addColorStop(i/10,col[(i + step)%col.length]);
ticker=ticker+10;
if (ticker>=196){
	ticker=0;
	step++;
	}
g.fillStyle=grd;
g.fillRect(0,0,1600,700);
}

function preperation(){
	setInterval('drawBackground()',100);
  }
</script>
<style type="text/css">
#myCanvas{
 z-index:2;	
 position:absolute; left:0px; top:-5px;
}
#background{
	z-index:1;
	position:absolute;
	left:0px;
	top:0px;
}
</style>
</head>
<body onLoad="preperation()">
<canvas id="myCanvas" width="900" height="600" >
Your browser does not support the HTML5 canvas tag.
</canvas>
<canvas id="background" width="1600" height="700" ></canvas>
<script>
var x=new Array(0,12,54,18,28,0,-28,-18,-54,-12,0);    //五角星样品坐标xx数组
var y=new Array(-53,-17,-17,1,45,19,45,1,-17,-17,-53); //五角星样品坐标y数组

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d"); //获得画笔
//样品数组x轴坐标 a , 和y轴坐标 b
//指定位置[locationX,locationY]
//真实五角星的大小,与样品五角星尺寸之比 f
//五角星画完后,旋转的角度 rotation
function star(a,b,locationX,locationY,f,rotation){
ctx.save();//记录画图(画笔)的初始环境
ctx.translate(locationX,locationY);
ctx.rotate(rotation*Math.PI/180.0);
ctx.beginPath();
ctx.moveTo(Math.round(a[0]*f),Math.round(b[0]*f));
for (var i=1;i<a.length;i++)
ctx.lineTo(Math.round(a[i]*f),Math.round(b[i]*f));
ctx.closePath();
ctx.fillStyle="yellow";
ctx.fill();
ctx.restore();//还原画图(画笔)的初始环境
}
star(x,y,165,165,1.4,0);//画大五角星
star(x,y,301,65,0.5,30);//画小五角星
star(x,y,362,126,0.5,-30);//画小五角星
star(x,y,359,216,0.5,0);//画小五角星
star(x,y,301,273,0.5,30);//画小五角星
</script>
</body>
</html>

运行效果截图:

第二个: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")
}

运行效果截图:

猜你喜欢

转载自blog.csdn.net/m0_69824302/article/details/133419456