前回、三角形を描画したので、これを組み合わせて、平面と直方体を描画します。
MainWindow.csに以下のコードを追加してください。
// p0 -> p1 -> p2 -> p3 に対し、右ねじの方向に四角形を表示する
public static Model3DGroup CreatePlaneModel(Point3D p0, Point3D p1, Point3D p2, Point3D p3, SolidColorBrush brush = null)
{
var plane = new Model3DGroup();
plane.Children.Add(CreateTriangleModel(p0, p1, p3, brush));
plane.Children.Add(CreateTriangleModel(p2, p3, p1, brush));
return plane;
}
三角形を繋ぎ合わせるだけですから、簡単ですね!ただし、前回述べたように、この平面も表裏があるため、Cameraの位置には注意して下さい。
MainWindow.xamlのCameraを元に戻します。
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="60"
LookDirection="-1,-1,-1"
Position="5,5,5"
UpDirection="0,1,0" />
</Viewport3D.Camera>
MainWindow.csのコンストラクタで、平面を描画します。
public MainWindow()
{
InitializeComponent();
axis3DViewport.Children.Add(new XyzAxis3D() { Length = 4, Radius = 0.03 });
//var triangle = CreateTriangleModel(new Point3D(0, 1, 0), new Point3D(0, 0, 1), new Point3D(1, 0, 0), Brushes.Red);
var plane = CreatePlaneModel(new Point3D(0, 1, 1), new Point3D(0, 0, 1), new Point3D(1, 0, 0), new Point3D(1, 1, 0), Brushes.Blue);
axis3DViewport.Children.Add(new ModelVisual3D() { Content = plane });
}
実行結果は以下のようになります。
では、平面を組み合わせて、直方体を作成しましょう。六枚の平面を作成するため、コードが長くなりますが、ご辛抱ください。以下のコードをMainWindow.csに追加します。
// width -> x axis length, height -> y axis length, depth -> z axis length,
public static Model3DGroup CreateCubeModel(Point3D centerPoint, double width, double height, double depth, SolidColorBrush brush = null)
{
var cube = new Model3DGroup();
var p0 = new Point3D(centerPoint.X - width / 2, centerPoint.Y - height / 2, centerPoint.Z - depth / 2);
var p1 = new Point3D(p0.X + width, p0.Y, p0.Z);
var p2 = new Point3D(p0.X + width, p0.Y, p0.Z + depth);
var p3 = new Point3D(p0.X, p0.Y, p0.Z + depth);
var p4 = new Point3D(p0.X, p0.Y + height, p0.Z);
var p5 = new Point3D(p0.X + width, p0.Y + height, p0.Z);
var p6 = new Point3D(p0.X + width, p0.Y + height, p0.Z + depth);
var p7 = new Point3D(p0.X, p0.Y + height, p0.Z + depth);
//front side triangles
cube.Children.Add(CreateTriangleModel(p3, p2, p6, brush));
cube.Children.Add(CreateTriangleModel(p3, p6, p7, brush));
//right side triangles
cube.Children.Add(CreateTriangleModel(p2, p1, p5, brush));
cube.Children.Add(CreateTriangleModel(p2, p5, p6, brush));
//back side triangles
cube.Children.Add(CreateTriangleModel(p1, p0, p4, brush));
cube.Children.Add(CreateTriangleModel(p1, p4, p5, brush));
//left side triangles
cube.Children.Add(CreateTriangleModel(p0, p3, p7, brush));
cube.Children.Add(CreateTriangleModel(p0, p7, p4, brush));
//top side triangles
cube.Children.Add(CreateTriangleModel(p7, p6, p5, brush));
cube.Children.Add(CreateTriangleModel(p7, p5, p4, brush));
//bottom side triangles
cube.Children.Add(CreateTriangleModel(p2, p3, p0, brush));
cube.Children.Add(CreateTriangleModel(p2, p0, p1, brush));
return cube;
}
直方体の各頂点を指定するのは面倒くさいので、中心座標と高さ、縦幅、横幅を指定する様にしました。
では、MainWindow.csのコンストラクタを以下のように変更します。
public MainWindow()
{
InitializeComponent();
axis3DViewport.Children.Add(new XyzAxis3D() { Length = 4, Radius = 0.03 });
//var triangle = CreateTriangleModel(new Point3D(0, 1, 0), new Point3D(0, 0, 1), new Point3D(1, 0, 0), Brushes.Red);
//var plane = CreatePlane(new Point3D(0, 1, 1), new Point3D(0, 0, 1), new Point3D(1, 0, 0), new Point3D(1, 1, 0), Brushes.Blue);
var cube = CreateCubeModel(new Point3D(0, 0, 0), 2, 1, 3, Brushes.Yellow);
axis3DViewport.Children.Add(new ModelVisual3D() { Content = cube });
}
実行結果は以下のようになります。
直方体は全ての平面が表を向いているため、どの角度からでもCameraで見ることができます。ただし、この場合はCameraの座標に注意し、必ず直方体の方向をCameraが向いているようにしてください。