用C++代码生成一面五星红旗

原始问题的背景和描述

这个问题的来源另外一篇博客里面已经提到过,stackexchange上一个有趣的C++代码竞赛的博客,它的来源是:StackExchange上的原始问题及答案

比赛基于下面的代码:基础代码链接 ,这个在博文我的另一CSDN博客中也已经给出,如果原始链接无法访问可以备用。

已经提到,我感兴趣的是基于这个代码如何生成一面五星红旗。红旗的设计图如下,也在我的上一篇博客搜索给出过。

计算和代码

首先,五星红旗颜色简单,只有红色黄色两种。从减法色(RGB)的角度看,黄色就是白色光中减去红色和绿色。所以,背景是红色很单一,关键就是如何减掉五角星区域内的绿色,即改写unsigned char GR(int i,int j)函数。

考虑到问题不是那么简单直接,先不考虑字符数仅为140个(一twitter)的限制,先做出来再说。

我打算用Mathematica完成逻辑部分。代码如下:

ClearAll["Global`*"];
sol = Solve[{(x - x0)^2 + (y - y0)^2 ==
      r^2, (y - y0) (x1 - x0) == (x - x0) (y1 - y0)}, {x, y}] //
   FullSimplify;
p1 = {x, y} /. sol[[2]] // Simplify;
a = {x0, y0};

p2 = RotationTransform[2 Pi/5, a][p1] // Simplify;
p3 = RotationTransform[2 Pi/5, a][p2] // Simplify;
p4 = RotationTransform[2 Pi/5, a][p3] // Simplify;
p5 = RotationTransform[2 Pi/5, a][p4] // Simplify;

q1 = {x, y} /. sol[[1]] // Simplify;
q2 = RotationTransform[2 Pi/5, a][q1] // Simplify;
q3 = RotationTransform[2 Pi/5, a][q2] // Simplify;
q4 = RotationTransform[2 Pi/5, a][q3] // Simplify;
q5 = RotationTransform[2 Pi/5, a][q4] // Simplify;

(P1 = Limit[
       Limit[{p1, p2, p3, p4, p5} /. {x1 -> 100, y1 -> 200, r -> 60},
        x0 -> 100], y0 -> 100] // Simplify // N // Round);
(P2 = Limit[
       Limit[{q1, q2, q3, q4, q5} /. {x1 -> 100, y1 -> 100, r -> 20},
        x0 -> 200], y0 -> 180] // Simplify // N // Round);
(P3 = Limit[
       Limit[{q1, q2, q3, q4, q5} /. {x1 -> 100, y1 -> 100, r -> 20},
        x0 -> 200], y0 -> 40] // Simplify // N // Round);
(P4 = Limit[
       Limit[{q1, q2, q3, q4, q5} /. {x1 -> 100, y1 -> 100, r -> 20},
        x0 -> 240], y0 -> 140] // Simplify // N // Round);
(P5 = Limit[
       Limit[{q1, q2, q3, q4, q5} /. {x1 -> 100, y1 -> 100, r -> 20},
        x0 -> 240], y0 -> 80] // Simplify // N // Round);

line[P_] := (P[[1, 1]] - P[[2, 1]]) y + P[[2, 1]] P[[1, 2]] -
  P[[1, 1]] P[[2, 2]] + x (P[[2, 2]] - P[[1, 2]])
lines[P_] := {[email protected][[{1, 3}]], [email protected][[{3, 5}]], [email protected][[{5, 2}]],
  [email protected][[{2, 4}]], [email protected][[{4, 1}]]}

pc01 = lines[P1];
pc02 = lines[P2];
pc03 = lines[P3];
pc04 = lines[P4];
pc05 = lines[P5];

innerQ[rp_, pc_] :=
 Not[(pc[[1]] /. rp) >= 0 && (pc[[3]] /. rp) >= 0] &&
  Not[(pc[[1]] /. rp) >= 0 && (pc[[4]] /. rp) >= 0] &&
  Not[(pc[[2]] /. rp) >= 0 && (pc[[4]] /. rp) >= 0] &&
  Not[(pc[[2]] /. rp) >= 0 && (pc[[5]] /. rp) >= 0] &&
  Not[(pc[[3]] /. rp) >= 0 && (pc[[5]] /. rp) >= 0]

testQ[pc01_] :=
 Not[(pc01[[1]]) >= 0 && (pc01[[3]]) >= 0] &&
  Not[(pc01[[1]]) >= 0 && (pc01[[4]]) >= 0] &&
  Not[(pc01[[2]]) >= 0 && (pc01[[4]]) >= 0] &&
  Not[(pc01[[2]]) >= 0 && (pc01[[5]]) >= 0] &&
  Not[(pc01[[3]]) >= 0 && (pc01[[5]]) >= 0]

Print[[email protected] // CForm]
Print[""]
Print[[email protected] // CForm]
Print[""]
Print[[email protected] // CForm]
Print[""]
Print[[email protected] // CForm]
Print[""]
Print[[email protected] // CForm]

上面这段代码直接输出五个五角星区域的逻辑判断为C/C++代码形式,几乎不用什么修改。唯一的缺点是太长了。把它们OR(||)起来就是GR函数中需要的部分。

修改好的完整的C++代码我是这样弄的:

// NOTE: compile with g++ filename.cpp -std=c++11

#include <iostream>
#include <cmath>
#include <cstdlib>
#define DIM1 600
#define DIM2 400
#define DM1 (DIM1-1)
#define DM2 (DIM2-1)
#define _sq(x) ((x)*(x)) // square
#define _cb(x) abs((x)*(x)*(x)) // absolute value of cube
#define _cr(x) (unsigned char)(pow((x),1.0/3.0)) // cube root

unsigned char GR(int,int);
unsigned char BL(int,int);

unsigned char RD(int i,int j){
// YOUR CODE HERE
    return 255;
}
unsigned char GR(int i,int j){
    int x=i,y=j;
// YOUR CODE HERE
return (!(-9500+109*x-35*y>=0&&9234-114*y>=0)&&!(-9500+109*x-35*y>=0&&-18128+68*x+92*y>=0)&&!(-4528-68*x+92*y>=0&&-18128+68*x+92*y>=0)&&!(-4528-68*x+92*y>=0&&12300-109*x-35*y>=0)&&!(9234-114*y>=0&&12300-109*x-35*y>=0))||(!(3656+13*x-36*y>=0&&10074-30*x-24*y>=0)&&!(3656+13*x-36*y>=0&&-8188+38*x+2*y>=0)&&!(-8897+10*x+37*y>=0&&-8188+38*x+2*y>=0)&&!(-8897+10*x+37*y>=0&&2176-31*x+21*y>=0)&&!(10074-30*x-24*y>=0&&2176-31*x+21*y>=0))||(!(6374-28*x-25*y>=0&&5407-32*x+19*y>=0)&&!(6374-28*x-25*y>=0&&-1830+15*x-35*y>=0)&&!(-7784+37*x+4*y>=0&&-1830+15*x-35*y>=0)&&!(-7784+37*x+4*y>=0&&-3314+8*x+37*y>=0)&&!(5407-32*x+19*y>=0&&-3314+8*x+37*y>=0))||(!(5572-2*x-38*y>=0&&10043-37*x-10*y>=0)&&!(5572-2*x-38*y>=0&&-7044+36*x-13*y>=0)&&!(-10206+24*x+30*y>=0&&-7044+36*x-13*y>=0)&&!(-10206+24*x+30*y>=0&&456-21*x+31*y>=0)&&!(10043-37*x-10*y>=0&&456-21*x+31*y>=0))||(!(6562-17*x-34*y>=0&&8406-38*x+6*y>=0)&&!(6562-17*x-34*y>=0&&-4563+27*x-27*y>=0)&&!(-9758+34*x+17*y>=0&&-4563+27*x-27*y>=0)&&!(-9758+34*x+17*y>=0&&-1834-6*x+38*y>=0)&&!(8406-38*x+6*y>=0&&-1834-6*x+38*y>=0))?255:0;
}
unsigned char BL(int i,int j){
// YOUR CODE HERE
    return 0;
}

void pixel_write(int,int);
FILE *fp;
int main(){
fp = fopen("MathPic.ppm","wb");
fprintf(fp, "P6\n%d %d\n255\n", DIM1, DIM2);
for(int j=0;j<DIM2;j++)
for(int i=0;i<DIM1;i++)
pixel_write(i,j);
fclose(fp);
return 0;
}
void pixel_write(int i, int j){
static unsigned char color[3];
color[0] = RD(i,j)&255;
color[1] = GR(i,j)&255;
color[2] = BL(i,j)&255;
fwrite(color, 1, 3, fp);
}

它的输出已经是一面五星红旗了。用XnView转ppmpng格式如下:

遗憾的是,我所修改的GR函数中的逻辑判断太长,远超一个twitter和140字符的要求。需要一些特殊技巧来压缩,目前我还做不到。

所以,我是来征集一个代码压缩技巧的。

……

问谁又能做到?

……

——Beyond

时间: 2024-08-09 02:19:07

用C++代码生成一面五星红旗的相关文章

bboss自动代码生成工具使用指南

本文介绍bboss自动代码生成工具使用方法 工具在线浏览效果: http://gencode.bbossgroups.com 在介绍之前首先了解一下bboss自动代码生成工具能帮助我们做哪些事情. 通过自动代码生成框架,根据模板可以自动生成数据库表的增.删.改.分页查询.列表查询.国际化功能对应的java.jsp程序和配置文件,包括: 1.mvc控制器 2.业务组件 3.PO实体类 4.jsp文件 可以定制不同风格的界面模板,目前提供了一套bboss平台的基础ui风格和一套bboss普通ui风格

iOS开发——代码生成TabBar与视图切换详解

我在之前多篇博客中讲解了在不使用storyboard而使用nib文件的情况下,使用代码生成导航栏并进行跳转,具体可以参考<iOS开发--界面跳转与返回及视图类型详解><iOS纯代码实现界面建立.跳转.导航栏(无storyboard.无nib)(Objective-C)>.今天我来讲解下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转.代码示例已经上传至:https://github.com/chenyufeng1991/TabBarTest   . (1)

在Geogebra中制作生成五角星的宏用于五星红旗

引子 在Geogebra中也提供了自定义按钮或类似宏的功能.虽然简单,但是容易忘记,所以,找一个例子记录下来以备不时之需. 准备 学习新东西,最好是从理解和解决实际问题实际案例入手,比较好的例子是用Geogebra绘制一幅五星红旗.从网络上找到五星红旗设计草图如下,包括长宽比例,星的位置和方向等详细信息. 分析 从图上发现: 五星红旗长和宽的比例是30:20: 有五星的区域仅占左上角的1/4相似矩形: 大五星外接圆半径如果是3,小五星外接圆半径为1: 所有五星的外接圆圆心易定,都是整数格点位置:

[jQuery编程挑战]005 使用最短的代码生成元素的闪烁效果

<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8"/> <title>使用最短的代码生成元素的闪烁效果</title> <style type="text/css"> .blink{ width: 150px; height: 150px; -webkit-border-radius: 50%

Impala中的代码生成技术

Cloudera Impala是一种为Hadoop生态系统打造的开源MPP(massive parallel processing)数据库,它主要为分析型查询负载而设计,而非OLTP.Impala能最大限度地利用现代硬件和高效查询执行的最新技术.LLVM下的运行时代码生成就是用来提升执行性能的技术之一. LLVM简介 LLVM是一个编译器及相关工具的库(toolchain),它不同于独立应用式(stand-alone)的传统编译器,LLVM是模块化且可重用的.它允许Impala这样的应用在运行的

用Python的Turtle模块绘制五星红旗

Edit 用Python的Turtle模块绘制五星红旗 在Udacity上课时学到了python的turtle方法,这是一个很经典的用来教小孩儿编程的图形模块,最早起源于logo语言.python本身内置了这个模块,其可视化的方法可以帮助小孩儿对编程的一些基本理念有所理解. 在作业提交的论坛里看到很多turtle画出来的精美图形,想不出什么要画的东西,于是决定拿五星红旗来练练手. 前期准备 五星红旗绘制参数 Turtle官方文档 turtle的基本操作 # 初始化屏幕 window = turt

iOS开发——代码生成TabBar与视图切换具体解释

我在之前多篇博客中解说了在不使用storyboard而使用nib文件的情况下.使用代码生成导航栏并进行跳转,具体能够參考<iOS开发--界面跳转与返回及视图类型具体解释><iOS纯代码实现界面建立.跳转.导航栏(无storyboard.无nib)(Objective-C)>. 今天我来解说下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转.代码演示样例已经上传至:https://github.com/chenyufeng1991/TabBarTest  

NHibernate之旅(18):初探代码生成工具使用

本节内容 引入 代码生成工具 结语 引入 我们花了大量的篇幅介绍了相关NHibernate的知识.一直都是带着大家手动编写代码,首先创建数据库架构.然后编写持久化类和映射文件,最后编写数据操作方法.測试方法. 这是典型的数据库驱动开发(DbDD,Database-Driven Developent)技术.可是自己不是这样做的,我先编写持久化类和映射文件,然后偷偷的使用SchemaExport工具把数据库生成了.按上面的步骤写文章的,关于SchemaExport工具就是下一篇的事情了,这篇说说利用

读取数据库信息构建视图字段的备注信息,方便程序代码生成

在很多情况下,我们开发都需要有一个快速的代码生成工具用来提高开发效率,代码生成工具很多信息都是读取数据库的表.视图等元数据进行对象表信息的完善,有了这些信息,我们就可以在普通的实体类代码里面添加属性字段的中文注释,或者在Winform或者Web界面的快速生成的时候,可以在查询框或者界面编辑的时候,充当标签提示等处理信息.但是,一般情况下视图的备注信息是没有的,但是视图和表之间是存在一定的关系的,虽然不同数据库系统对于它们的信息对应不一定一致,但是我们可以把它们的对应关系寻找出来就可以给视图字段增