关于镂空正方体的作图

  还在苦苦钻研画图板的我,被老师要求画出分形,当时我还没学过递归,就苦苦挣扎着用if 和for语句来完成,结果就是
苦苦挣扎了两个小时,依然想不到合适的算法,然后我的老师走过来告诉我说,可以在函数里面运行自己啊,然后就给我演
示了一些简单的操作,便给我下定任务,用递归函数画出中间镂空的正方体,也就是,假设每个大正方体由3*3*3个小正方
体组成,由于前后上下左右镂空,就只会剩下20个,然后通过分形,让每一个小正方体再分裂成20个更小的正方体,依次
分裂,并最终能够通过控制简单变量的数值来控制分裂次数,于是,我漫长的代码作图,便开始了。首先,我们分析,这一次是画立方体,而不是画简单的平面图形,但是程序里并没有可以直接在2d平面上作3d图的代码,
于是,我们只能自己用透视画法,画出正方体的三个面,来凸显立体感,而画多边形,我们就需要用到polygon,然后给
三个面上不同的颜色,这样才易于区分,然后我们可以先把其他的框架代码敲出来;
package 画图;import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JFrame;import org.omg.PortableServer.POAOperations;public class Draw3D {public void draw3drect(){JFrame jf = new JFrame();jf.setSize(1200,1000);jf.setLocationRelativeTo(null);jf.setLayout(new FlowLayout());jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JButton bt = new JButton("draw");jf.add(bt);jf.setVisible(true);Graphics gr = jf.getGraphics();Graphics gb = jf.getGraphics();Graphics gg = jf.getGraphics();  //创建三个画笔,分别画三个不同的面}public static void main(String[] args) {Draw3D a = new Draw3D();a.draw3drect();}}
这样我们先简单地创建了一个用于画图的界面,之后我们需要再创建一个界面来写入我们的接口,也就是动作监听器;
package 画图;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class rect3dlistener implements ActionListener{ //写入动作监听器,监听我们的draw按钮Graphics gb,gr,gg;public void actionPerformed(ActionEvent e) {}
}
之后我们再在我们的主类中实例化监听器,并实现两个类中画笔的对接,于是我们在主类中窗口可视化后面再写入;
rect3dlistener lis = new rect3dlistener();bt.addActionListener(lis);    //在按钮bt上加入动作监听器lis.gb=gb;lis.gg=gg;lis.gr=gr;    //实现两个类中画笔对接
  这样我们的基本框架就已完成,接下来就是最难的画立方体,我的想法是,我们先写入一个方法,让他可以执行画出20
个正方体框架的操作,而这个方法我们终究是要写入监听器的方法中,所以它需要在含有监听器的类中被调用,于是,我
们决定在含有监听器的类中,写入这个方法;

package 画图;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class rect3dlistener implements ActionListener{ //写入动作监听器,监听我们的draw按钮Graphics gb,gr,gg;public void actionPerformed(ActionEvent e) {}public void draw(int x1,int y1,int r,int d,int i ){ //我们给这个方法取名draw,我们根据我们的需//要写入变量,i是控制循环次数的变量if(i<=0){return;}gb.setColor(Color.blue);                           gr.setColor(Color.red);gg.setColor(Color.green);Polygon polo = new Polygon();Polygon polf = new Polygon();Polygon polr = new Polygon();polo.addPoint(x1, y1);polo.addPoint(x1+r, y1);polo.addPoint(x1+d+r, y1-d);polo.addPoint(x1+d, y1-d);polf.addPoint(x1, y1);polf.addPoint(x1, y1+r);polf.addPoint(x1+r, y1+r);polf.addPoint(x1+r, y1);polr.addPoint(x1+r, y1);polr.addPoint(x1+r, y1+r);polr.addPoint(x1+r+d, y1+r-d);polr.addPoint(x1+r+d, y1-d);gr.fillPolygon(polo);gb.fillPolygon(polr);gg.fillPolygon(polf);draw(x1+r,y1,r,d, i);draw(x1+r+r,y1,r,d, i);draw(x1-d,y1+d,r,d, i);draw(x1-d+r+r,y1+d,r,d, i);draw(x1-d-d,y1+d+d,r,d, i);draw(x1-d-d+r,y1+d+d,r,d, i);draw(x1-d-d+r+r,y1+d+d,r,d, i);draw(x1,y1-r,r,d, i);draw(x1+r+r,y1-r,r,d, i);draw(x1-d-d,y1-r+d+d,r,d, i);draw(x1-d-d+r+r,y1-r+d+d,r,d, i);draw(x1,y1-r-r,r,d, i);draw(x1+r,y1-r-r,r,d, i);draw(x1+r+r,y1-r-r,r,d, i);draw(x1-d,y1+d-r-r,r,d, i);draw(x1-d+r+r,y1+d-r-r,r,d, i);draw(x1-d-d,y1+d+d-r-r,r,d, i);draw(x1-d-d+r,y1+d+d-r-r,r,d, i);draw(x1-d-d+r+r,y1+d+d-r-r,r,d,i);}
}
  这时候,我们只需要输入i=3,在进入这个方法后,这个方法就会自动以我们输入的数据为基准,又左到右,由后到前,
由下到上的顺序画出每一个正方体,因为符合投影规则,所以后面的正方体总是正确的被前面的所覆盖。这时候,我们
就需要考虑分形了,但是我们又不能再去改变这个draw方法,所以为了方便我们决定再定义一个方法,与draw并列;
public void drawagain(int x1,int y1,int r,int d,int i ,int n){n--; //这个方法前五个变量用来附给draw方法,n变量用来控制自身循环次数if(n<0){return;}draw(x1,y1,r,d,i); //先运行一次draw方法,画出最大的立方体框架//接下来每次都将正方体的边长缩小至原来的三分之一,实现分形//但是想要找到下一次分裂时,起始正方体的起始点坐标并不容易,如果//有某些人数学能力并不强(比如我),建议先写出大概位置,再根据运行//结果进行调整,我自己就是慢慢把坐标试出来的。drawagain(x1+d/3+d/3                ,y1+(r/3)*2-(d/3)*2,r/3,d/3,i,n);drawagain(x1+r+d/3+d/3         ,y1+(r/3)*2-(d/3)*2,r/3,d/3,i,n);drawagain(x1+r+r+d/3+d/3      ,y1+(r/3)*2-(d/3)*2,r/3,d/3,i,n);drawagain(x1-d    +d/3+d/3      ,y1+(r/3)*2-(d/3)*2+d,r/3,d/3,i,n);drawagain(x1-d+r+r+d/3+d/3 ,y1+(r/3)*2-(d/3)*2+d,r/3,d/3,i,n);drawagain(x1-d-d+d/3+d/3     ,y1+(r/3)*2-(d/3)*2+d+d,r/3,d/3,i,n);drawagain(x1-d-d+r+d/3+d/3   ,y1+(r/3)*2-(d/3)*2+d+d,r/3,d/3,i,n);drawagain(x1-d-d+r+r+d/3+d/3,y1+(r/3)*2-(d/3)*2+d+d,r/3,d/3,i,n);drawagain(x1 +d/3+d/3,y1+(r/3)*2-(d/3)*2-r       ,r/3,d/3,i,n);drawagain(x1+r+r+d/3+d/3      ,y1+(r/3)*2-(d/3)*2-r,r/3,d/3,i,n);drawagain(x1-d-d +d/3+d/3     ,y1+(r/3)*2-(d/3)*2-r+d+d ,r/3,d/3,i,n);drawagain(x1-d-d+r+r+d/3+d/3,y1+(r/3)*2-(d/3)*2-r+d+d     ,r/3,d/3,i,n);drawagain(x1+d/3+d/3                ,y1+(r/3)*2-(d/3)*2-r-r            ,r/3,d/3,i,n);drawagain(x1+r+d/3+d/3         ,y1+(r/3)*2-(d/3)*2-r-r            ,r/3,d/3,i,n);drawagain(x1+r+r+d/3+d/3      ,y1+(r/3)*2-(d/3)*2-r-r            ,r/3,d/3,i,n);drawagain(x1-d +d/3+d/3           ,y1+(r/3)*2-(d/3)*2+d-r-r       ,r/3,d/3,i,n);drawagain(x1-d+r+r +d/3+d/3  ,y1+(r/3)*2-(d/3)*2+d-r-r      ,r/3,d/3,i,n);drawagain(x1-d-d +d/3+d/3      ,y1+(r/3)*2-(d/3)*2+d+d-r-r   ,r/3,d/3,i,n);drawagain(x1-d-d+r+d/3+d/3 ,y1+(r/3)*2-(d/3)*2+d+d-r-r,r/3,d/3,i,n);drawagain(x1-d-d+r+r+d/3+d/3,y1+(r/3)*2-(d/3)*2+d+d-r-r  ,r/3,d/3,i,n);
  这样,n就是我们需要大正方体分裂的次数,我们可以再运行时给它附上我们所需要的值,来控制分裂次数。
现在,我们唯一要做的,就是把drawagain方法写入动作监听器,让我们每次点击“draw“”按钮的时候,drawagain方
法能够被运行;
public void actionPerformed(ActionEvent e) {drawagain(400,600,243,81,3,5);//400和600分别对应x1和y1,243和81对应r和d,3是i的赋值,不可改变,n是分裂次数}
  我们在监听器中写入了drawagain,并赋值,这样,每次我们点击“draw”按钮,就可以得到我们想要的图形了。效果大概是这样

关于镂空正方体的作图相关推荐

  1. tkz-euclide作图教程02 | 立体几何作图示例

    作图要点:/.style定义元素属性风格:\tkzDefLine和\tkzInterLL 计算两直线交点:\tkzDefMidPoint定义中点 今天我们来作一个立体几何图形:正方体中取一个正六边形截 ...

  2. 纯CSS实现3D正方体动画效果

    目录 前言 正文 1.基本架构 2.书写每个div样式 3.为需要产生动画的一面单独设置样式 4.设置鼠标hover效果 5.优化 总结 前言 纯CSS实现3D正方体动画效果,此方法是通过transf ...

  3. 尺规作图及其研究意义

    0x01 什么是尺规作图? 一般定义 尺规作图是指用无刻度的直尺和圆规作图. 尺规作图是起源于古希腊的数学课题. 只使用圆规和直尺,并且只准许使用有限次,来解决不同的平面几何作图题. 尺规作图使用的直 ...

  4. OpenGl(二)点线设置、多边形镂空

    1. 改变点的大小 OpenGL中默认点的大小是1个像素,使用函数glPointSIze可以调整点的大小,入参是GLfloat,相当于是浮点数. 相关代码: void myDisplay(void) ...

  5. matlab在曲线给命名,matlab 利用xlsread画图,怎么将一组excel数据导入,通过matlab作图...

    Matlab 循环 for 语句 xlsread EXCEL表格数据导入 画图 Matlab的 xlsread() 函数可以将Excel数据到matlab工作空间,然后就可以根据读入据作图.下面给出操 ...

  6. python怎么做彩票概率_用Python一次性把论文作图与数据处理全部搞定!

    一入科研深似海-- 年底将近,"防脱发用生姜还是黑芝麻?",研究僧们又开始为自己所剩无几的头发发愁了. 文献看到头秃,前沿课题总是无缘 置顶了一页实验组微信群.QQ群,想追踪前沿文 ...

  7. r语言 断轴 画图_R语言基础画图/绘图/作图

    R语言基础画图 R语言免费且开源,其强大和自由的画图功能,深受广大学生和可视化工作人员喜爱,这篇文章对如何使用R语言作基本的图形,如直方图,点图,饼状图以及箱线图进行简单介绍. 0 结构 每种图形构成 ...

  8. 牧小熊:Adobe Illustrator 在科研作图中的应用!

    聂雄伟,华中农业大学,Datawhale原创作者. 关于大数据的完整讲解! 电商数据分析项目总结! 数据项目总结:蛋壳公寓租金分析! 数据项目总结:王者荣耀总决赛预测! 你要的用户画像实践来了! 基于 ...

  9. qt 实现窗口局部镂空,并截图显示。

    主要实现2 个功能点: 1 截图 2 窗口镂空 实现截图主要使用QGuiApplication::primaryScreen() 获取到QScreen ,然后调用QGuiApplication::gr ...

最新文章

  1. php导出excel方法,PHP导出EXCEL简单实用方法
  2. 关于封装了gevent的request grequest库的使用与讨论
  3. 同构多核和异构多核简单介绍
  4. window文件过长无法删除的处理方式
  5. ubuntu镜像下载地址(国内镜像源)
  6. 系统架构设计师考试大纲
  7. 前端学习(874):解绑事件兼容方案
  8. word没有显示endnote_Word2007或2010未显示EndNote工具条的解决方法 | 科研动力
  9. 程序员心髓:移动应用API设计10大技巧
  10. OSI七层模型及TCP/IP五层模型
  11. Android 开机动画的制作
  12. HTML table border 属性
  13. 太平洋车险条款 太平洋保险 条款 中国保险机动车交通事故责任强制保险条款 中国保险行业协会机动车综合商业保险示范条款 中国太平洋财产保险股份有限公司神行车保机动车损失保险(IACJQL0001)条款
  14. 语音社交聊天app受欢迎的特点有哪些?
  15. 关于数据治理的读书笔记 - 什么是数据战略?
  16. html输入框密码颜色,css解决浏览器输入框记住账号密码后的背景色
  17. 李宏毅2020机器学习深度学习 笔记1(理论上持续更新中)
  18. Maya如何切换中英文
  19. tensorflow2.X, TensorFlow Addons 版本的匹配选择
  20. 【医学图像处理】CT成像技术之CT剂量

热门文章

  1. python docx表格宽度_Python:如何調整docx中表格的行高度
  2. 头条号如何快速涨100W+粉丝?
  3. matplotlib matplotlib绘制条形图、散点图(三)
  4. python拟合非线性模型_初学Python拟合Langmuir非线性方程
  5. Spring | IOC技术之Bean的配置与实例化
  6. 找不到msvcp140.dll无法继续执行代码,怎么解决?
  7. 递归与分形(二)--谢尔斯宾三角形,谢尔斯宾地毯,门格海绵
  8. 【Chain-of-Thought 专题】Self-consistency Improves Chain Of Thought Reasoning in Language Models
  9. 法语难学吗-法语中的许多怎么说
  10. 怎么做手机App测试?app测试详细流程和方法介绍(即学即用宝典)