using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public class v4
{
public double x;
public double y;
public double z;
public double h;
public v4(double _x, double _y, double _z, double _h)
{
this.x = _x;
this.y = _y;
this.z = _z;
this.h = _h;
}
}
public bool cross(double ax, double ay, double bx, double by)
{
return (ax * by - ay * bx) < 0.0;
}
public class matrix
{
public v4[] pts;
public matrix(v4[] _pts)
{
pts = new v4[_pts.Length];
_pts.CopyTo(this.pts, 0);
}
}
public v4[] cube = new v4[8];
public matrix rotation_matrix;
public matrix modif_matrix;
void init()
{
cube[0] = new v4(0, 0, 0, 1);
cube[1] = new v4(100, 0, 0, 1);
cube[2] = new v4(100, 100, 0, 1);
cube[3] = new v4(0, 100, 0, 1);
cube[4] = new v4(0, 0, 100, 1);
cube[5] = new v4(100, 0, 100, 1);
cube[6] = new v4(100, 100, 100, 1);
cube[7] = new v4(0, 100, 100, 1);
/*cube[0] = new v4(-50, -50, -50, 1);
cube[1] = new v4(50, -50, -50, 1);
cube[2] = new v4(50, 50, -50, 1);
cube[3] = new v4(-50, 50, -50, 1);
cube[4] = new v4(-50, -50, 50, 1);
cube[5] = new v4(50, -50, 50, 1);
cube[6] = new v4(50, 50, 50, 1);
cube[7] = new v4(-50, 50, 50, 1);*/
v4[] ret = new v4[4];
ret[0] = new v4(0.707, 0, 0, 0.002828);
ret[1] = new v4(0, 1, 0, 0);
ret[2] = new v4(0.707, 0, 0, -0.002828);
ret[3] = new v4(0, 40, 0, 1);
modif_matrix = new matrix(ret);
}
public v4 mult(v4 vect, matrix rotat)
{
v4 ret = new v4(0, 0, 0, 0);
ret.x = vect.x * rotat.pts[0].x + vect.y * rotat.pts[1].x +
vect.z * rotat.pts[2].x + vect.h * rotat.pts[3].x;
ret.y = vect.x * rotat.pts[0].y + vect.y * rotat.pts[1].y +
vect.z * rotat.pts[2].y + vect.h * rotat.pts[3].y;
ret.z = vect.x * rotat.pts[0].z + vect.y * rotat.pts[1].z +
vect.z * rotat.pts[2].z + vect.h * rotat.pts[3].z;
ret.h = vect.x * rotat.pts[0].h + vect.y * rotat.pts[1].h +
vect.z * rotat.pts[2].h + vect.h * rotat.pts[3].h;
ret.x /= ret.h;
ret.y /= ret.h;
ret.z /= ret.h;
if (Math.Abs(ret.h) < 0.000001)
return ret;
ret.h = 1;
return ret;
}
public void fill_rotation_matrix(double teta,
double x,
double y,
double z)
{
double c = Math.Cos(teta);
double s = Math.Sin(teta);
double norm = Math.Sqrt(x * x + y * y + z * z);
x = x / norm;
y = y / norm;
z = z / norm;
v4[] ret = new v4[4];
ret[0] = new v4(c + (1 - c) * x * x,
(1 - c) * x * y - s * z,
(1 - c) * x * z + s * y,
0);
ret[1] = new v4((1 - c) * x * y + s * z,
c + (1 - c) * y * y,
(1 - c) * y * z - s * x,
0);
ret[2] = new v4((1 - c) * z * x - s * y,
(1 - c) * y * z + s * x,
c + (1 - c) * z * z,
0);
ret[3] = new v4(0, 0, 0, 1);
rotation_matrix = new matrix(ret);
}
public matrix rotation(double teta,
double x,
double y,
double z)
{
v4[] ret = new v4[8];
cube.CopyTo(ret, 0);
fill_rotation_matrix(teta, x, y, z);
for (int i = 0; i < 8; ++i)
{
ret[i] = mult(ret[i], rotation_matrix);
}
return new matrix(ret);
}
public matrix rotation_project()
{
v4[] ret = new v4[8];
cube.CopyTo(ret, 0);
for (int i = 0; i < 8; ++i)
{
ret[i] = mult(ret[i], modif_matrix);
}
return new matrix(ret);
}
static int[] line_ind = new int[24] { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 4, 0, 5, 1, 6, 2, 7, 3 };
static int[] egde_ind = new int[24] { 3, 2, 1, 0, 0, 1, 5, 4, 1, 2, 6, 5, 2, 3, 7, 6, 3, 0, 4, 7, 4, 5, 6, 7 };
public void draw_line(v4 a, v4 b, int w)
{
Line ln = new Line();
ln.X1 = a.x;
ln.X2 = b.x;
ln.Y1 = a.y;
ln.Y2 = b.y;
ln.Stroke = Brushes.Coral;
ln.StrokeThickness = w;
this.canvas.Children.Add(ln);
}
public Point f(v4 a)
{
Point ret = new Point();
ret.X = a.x;
ret.Y = a.y;
return ret;
}
public void draw_edge(v4 a, v4 b, v4 c, v4 d)
{
if (cross(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y) == false)
{
LinearGradientBrush gr = new LinearGradientBrush();
Polygon polygon = new Polygon();
polygon.Points = new PointCollection() {
new Point(a.x, a.y),
new Point(b.x, b.y),
new Point(c.x, c.y),
new Point(d.x, d.y)
};
LinearGradientBrush lgb = new LinearGradientBrush(Color.FromRgb(0xAA, 0xBB, 0x70),
Color.FromRgb(0xFF, 0xFF, 0x00),
f(a), f(c));
polygon.Fill = lgb;
polygon.Stroke = Brushes.Black;
this.canvas.Children.Add(polygon);
}
}
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
public double angle = 0;
public MainWindow()
{
InitializeComponent();
init();
timer.Start();
timer.Interval = TimeSpan.FromSeconds(0.016);
timer.Tick += new EventHandler(timer_tick);
/*
matrix rotated = rotation_project();
for (int i = 0; i < 24; i += 2)
{
draw_line(rotated.pts[line_ind[i]],
rotated.pts[line_ind[i + 1]],
3);
}
v4[] dot = {new v4(1, 0, 0, 0),
new v4(0, 1, 0, 0),
new v4(0, 0, 1, 0)};
for (int i = 0; i < 3; ++i)
{
dot[i] = mult(dot[i], modif_matrix);
if (Math.Abs(dot[i].h) < 0.00001)
continue;
for (int j = 0; j < 8; ++j)
draw_line(dot[i], rotated.pts[j], 1);
}*/
}
public void timer_tick(object sender, EventArgs e)
{
canvas.Children.Clear();
matrix rotated = rotation(angle, 1, 1, 1);
for (int i = 0; i < 24; i += 4)
{
draw_edge(rotated.pts[egde_ind[i]],
rotated.pts[egde_ind[i + 1]],
rotated.pts[egde_ind[i + 2]],
rotated.pts[egde_ind[i + 3]]);
}
angle += 0.0192;
}
}
}