cscの作法 その357

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
MDIコンテナでボタンでフォームを表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ed0bfd1f-7a9c-a762-416b-b512cd0d44b4.png)


# サンプルコード

```
using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;

namespace App
{
public class form1: Form {
	private int maxLevel = 6;
	public form1() {
		BackColor = Color.Black;
		this.Text = "シェルピンスキーのギャスケット";
		ClientSize = new Size(700, 500);
		StartPosition = FormStartPosition.Manual;
		Location = new Point(150, 50);
	}
	protected override void OnPaint(PaintEventArgs e) {
		DrawSierpinskiGasket(e.Graphics, 319, 40, 30, 430, 609, 430, 0);
		base.OnPaint(e);
	}
	private void DrawSierpinskiGasket(Graphics g, int x1, int y1, int x2, int y2, int x3, int y3, int level) {
		if (level == maxLevel)
		{
			g.DrawLine(Pens.Lime, x1, y1, x2, y2);
			g.DrawLine(Pens.Lime, x2, y2, x3, y3);
			g.DrawLine(Pens.Lime, x3, y3, x1, y1);
		}
		else
		{
			int xx1 = (int)((x1 + x2) / 2.0);
			int yy1 = (int)((y1 + y2) / 2.0);
			int xx2 = (int)((x2 + x3) / 2.0);
			int yy2 = (int)((y2 + y3) / 2.0);
			int xx3 = (int)((x3 + x1) / 2.0);
			int yy3 = (int)((y3 + y1) / 2.0);
			DrawSierpinskiGasket(g, x1, y1, xx1, yy1, xx3, yy3, level + 1);
			DrawSierpinskiGasket(g, x2, y2, xx1, yy1, xx2, yy2, level + 1);
			DrawSierpinskiGasket(g, x3, y3, xx3, yy3, xx2, yy2, level + 1);
		}
	}
}
public class form2: Form {
	private const double PAI = 3.141592653589393238462643383279;
	private const double thetaOf60Degree = 60 * PAI / 180;
	private int maxLevel = 4;
	public form2() {
		BackColor = Color.Black;
		this.Text = "コッホ曲線";
		ClientSize = new Size(700, 500);
		StartPosition = FormStartPosition.Manual;
		Location = new Point(170, 70);
	}
	protected override void OnPaint(PaintEventArgs e) {
		DrawKochCurve(e.Graphics, 0, 100, 639, 100, 0);
		base.OnPaint(e);
	}
	private void DrawKochCurve(Graphics g, int x1, int y1, int x2, int y2, int level) {
		if (level == maxLevel)
		{
			g.DrawLine(Pens.Yellow, x1, 479 - y1, x2, 479 - y2);
		}
		else
		{
			int vx = (x2 - x1) / 3;
			int vy = (y2 - y1) / 3;
			int xx1 = x1 + vx;
			int yy1 = y1 + vy;
			int[] v1 = rotate(thetaOf60Degree, vx, vy);
			int xx2 = xx1 + v1[0];
			int yy2 = yy1 + v1[1];
			int[] v2 = rotate(-thetaOf60Degree, vx, vy);
			int xx3 = xx2 + v2[0];
			int yy3 = yy2 + v2[1];
			level++;
			DrawKochCurve(g, x1, y1, xx1, yy1, level);
			DrawKochCurve(g, xx1, yy1, xx2, yy2, level);
			DrawKochCurve(g, xx2, yy2, xx3, yy3, level);
			DrawKochCurve(g, xx3, yy3, x2, y2, level);
		}
	}
	private int[] rotate(double theta, int x, int y) {
		double sinTheta = Math.Sin(theta);
		double cosTheta = Math.Cos(theta);
		int x2 = (int)(cosTheta * x - sinTheta * y);
		int y2 = (int)(sinTheta * x + cosTheta * y);
		return new int[] { x2, y2 };
	}
}
public class form3: Form {
	public form3() {
		Text = "ray";
		ClientSize = new Size(200, 200);
		StartPosition = FormStartPosition.Manual;
		Location = new Point(200, 100);
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		Color clrBackground = Color.Black;
		g.FillRectangle(new SolidBrush(clrBackground), new Rectangle(0, 0, 200, 200));
		Rectangle rect = new Rectangle(0, 0, 200, 200);
		System.Collections.ArrayList obj3dArrayList;
		obj3dArrayList = new System.Collections.ArrayList();
		obj3dArrayList.Add(new Sphere(0.0, 0.0, 90.0, 100.0, 0.0, 0.0, 255.0));
		obj3dArrayList.Add(new Sphere(-180.0, -130.0, -110.0, 15.0, 255.0, 0.0, 0.0));
		obj3dArrayList.Add(new Sphere(-140.0, -140.0, -150.0, 20.0, 255.0, 200.0, 0.0));
		Graphics graphics = g;
		double px = (double) 0,
			py = (double) 0,
			pz = (double) 500;
		double lpx = (double) 200,
			lpy = (double) 200,
			lpz = (double) 200;
		double lvx = (double) -1.0,
			lvy = (double) -1.0,
			lvz = (double) -1.0;
		double fMax = 200.0;
		for (int i = rect.Left; i <= rect.Right; i++)
		{
			double x = Sphere.GetCoord(rect.Left, rect.Right, -fMax, fMax, i);
			for (int j = rect.Top; j <= rect.Bottom; j++)
			{
				double y = Sphere.GetCoord(rect.Top, rect.Bottom, fMax, -fMax, j);
				double t = 1.0E10;
				double vx = x - px, vy = y - py, vz = -pz;
				double mod_v = Sphere.modv(vx, vy, vz);
				vx = vx / mod_v;
				vy = vy / mod_v;
				vz = vz / mod_v;
				bool bShadow = false;
				Sphere spherehit = null;
				for (int k = 0; k < (int) obj3dArrayList.Count; k++)
				{
					Sphere sphn = (Sphere) obj3dArrayList[k];
					double taux = Sphere.GetSphereIntersec(sphn.cx, sphn.cy, sphn.cz, sphn.radius, px, py, pz, vx, vy, vz);
					if (taux < 0) continue;
					if (taux > 0 && taux < t)
					{
						t = taux;
						spherehit = sphn;
					}
				}
				Color color = Color.FromArgb(10, 20, 10);
				if (spherehit != null)
				{
					double itx = px + t * vx, ity = py + t * vy, itz = pz + t * vz;
					double tauxla = Sphere.GetSphereIntersec(spherehit.cx, spherehit.cy, spherehit.cz, spherehit.radius, lpx, lpy, lpz, itx - lpx, ity - lpy, itz - lpz);
					for (int k = 0; k < (int)obj3dArrayList.Count; k++)
					{
						Sphere sphnb = (Sphere)(obj3dArrayList[k]);
						if (sphnb != spherehit)
						{
							double tauxlb = Sphere.GetSphereIntersec(sphnb.cx, sphnb.cy, sphnb.cz, sphnb.radius, lpx, lpy, lpz, itx - lpx, ity - lpy, itz - lpz);
							if (tauxlb > 0 && tauxla < tauxlb)
							{
								bShadow = true;
								break;
							}
						}
					}
					double cost = Sphere.GetCosAngleV1V2(lvx, lvy, lvz, itx - spherehit.cx, ity - spherehit.cy, itz - spherehit.cz);
					if (cost < 0) cost = 0;
					double fact = 1.0;
					if (bShadow == true) fact = 0.5; else fact = 1.0;
					double rgbR = spherehit.clR * cost * fact;
					double rgbG = spherehit.clG * cost * fact;
					double rgbB = spherehit.clB * cost * fact;
					color = Color.FromArgb((int)rgbR, (int)rgbG, (int)rgbB);
					Pen pen = new Pen(color);
				}
				Brush brs = new SolidBrush(color);
				graphics.FillRectangle(brs, i, j, 1, 1);
				brs.Dispose();
			}
		}
		base.OnPaint(e);
	}
	class Sphere {
		public double cx,
			cy,
			cz,
			radius,
			clR,
			clG,
			clB;
		public Sphere(double x, double y, double z, double r, double clr, double clg, double clb) {
			cx = x;
			cy = y;
			cz = z;
			radius = r;
			clR = clr;
			clG = clg;
			clB = clb;
		}
		public static double GetCoord(double i1, double i2, double w1, double w2, double p) {
			return ((p - i1) / (i2 - i1)) * (w2 - w1) + w1;
		}
		public static double modv(double vx, double vy, double vz) {
			return System.Math.Sqrt(vx * vx + vy * vy + vz * vz);
		}
		void Move(double vx, double vy, double vz) {
			cx += vx;
			cy += vy;
			cz += vz;
		}
		void MoveTo(double vx, double vy, double vz) {
			cx = vx;
			cy = vy;
			cz = vz;
		}
		void RotX(double angle) {
			double y = cy * System.Math.Cos(angle) - cz * System.Math.Sin(angle);
			double z = cy * System.Math.Sin(angle) + cz * System.Math.Cos(angle);
			cy = y;
			cz = z;
		}
		void RotY(double angle) {
			double x = cx * System.Math.Cos(angle) - cz * System.Math.Sin(angle);
			double z = cx * System.Math.Sin(angle) + cz * System.Math.Cos(angle);
			cx = x;
			cz = z;
		}
		public static double GetSphereIntersec(double cx, double cy, double cz, double radius, double px, double py, double pz, double vx, double vy, double vz) {
			double A = (vx * vx + vy * vy + vz * vz);
			double B = 2.0 * (px * vx + py * vy + pz * vz - vx * cx - vy * cy - vz * cz);
			double C = px * px - 2 * px * cx + cx * cx + py * py - 2 * py * cy + cy * cy + pz * pz - 2 * pz * cz + cz * cz - radius * radius;
			double D = B * B - 4 * A * C;
			double t = -1.0;
			if (D >= 0)
			{
				double t1 = (-B - System.Math.Sqrt(D)) / (2.0 * A);
				double t2 = (-B + System.Math.Sqrt(D)) / (2.0 * A);
				if (t1 > t2) 
					t = t1; 
				else 
					t = t2;
			}
			return t;
		}
		public static double GetCosAngleV1V2(double v1x, double v1y, double v1z, double v2x, double v2y, double v2z) {
			return (v1x * v2x + v1y * v2y + v1z * v2z) / (modv(v1x, v1y, v1z) * modv(v2x, v2y, v2z));
		}
	}
}
	public partial class formMain: Form {
		public formMain() {
			Text = "formMain";
			ClientSize = new Size(120, 300);
			Button btn1 = new Button();
			btn1.Location = new Point(10, 50);
			btn1.Text = "Gasket";
			btn1.Click += btn1_Click;
			Button btn2 = new Button();
			btn2.Location = new Point(10, 100);
			btn2.Text = "Koch";
			btn2.Click += btn2_Click;
			Button btn3 = new Button();
			btn3.Location = new Point(10, 150);
			btn3.Text = "Ray";
			btn3.Click += btn3_Click;
			Controls.AddRange(new Control[] {
				btn1,
				btn2,
				btn3
			});
		}
		void btn1_Click(object sender, System.EventArgs e) {
			form1 f1 = new form1();
			f1.MdiParent = MdiParent;
			f1.Show();
		}
		void btn2_Click(object sender, System.EventArgs e) {
			form2 f1 = new form2();
			f1.MdiParent = MdiParent;
			f1.Show();
		}
		void btn3_Click(object sender, System.EventArgs e) {
			form3 f1 = new form3();
			f1.MdiParent = MdiParent;
			f1.Show();
		}
	}
	public partial class formMdi: Form {
		public formMdi() {
			Text = "formMdi";
			ClientSize = new Size(900, 550);
			IsMdiContainer = true;
			formMain ma = new formMain();
			ma.MdiParent = this;
			ma.Show();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new formMdi());
		}
	}
}






```


以上。