On Thursday, 16 December 2021 at 12:57:54 UTC, Salih Dincer wrote:
> Çok yakında 3B küpümüzü ve hayallerimiz ile sınırlı üç boyutlu dünyaya sağlam bir zıplama yapacağız :)
Bir haftadır birkaç başlık altında 3B dünyaya adım atmaya çalışıyorduk. Birlikte kodu geliştirip istediğimiz seviyeyi (derinliği olan 3 farklı nesneyi belli bir eksende döndürmeyi) sağladık...
Sonraki versiyonla bu kodu (ekrana 1 tane dörtyüzlü, 1 tane beş yüzü bulunan piramiti ve 5 tane de küp çizer) drawLine() ile değil de drawPolygon() ile yaparsanız çizgiler yerine içi dolu yüzeyler ile çalışabilmeniz mümkün. Başarılar..
import arsd.simpledisplay, std.stdio;
import std.algorithm, std.range;
import std.math, std.random;
enum windowWidth = 1200;
enum windowHeight = 640;
enum katSayı = 30;
enum açı = 6;
enum fps = katSayı * açı;
enum Boyut { X, Y, Z }
struct Nodes { double x, y, z; }
class PainterHelper {
SimpleWindow window;
Color backgroundColor;
Shape[] shapes;
this(int width, int height, string name, Color color = Color.black) {
this.window = new SimpleWindow(width, height, name);
this.backgroundColor = color;
window.draw.clear(backgroundColor);
shapes ~= new Tetrahedron(Nodes(-450, -200, -100), 100);
shapes ~= new Polyhedron(Nodes(-200, -200, -100), 100);//*
for(double x = 0, b = 25; x <= 500; x += 125, b += 15)
{
shapes ~= new Cube(Nodes(x, -200, -100), b);
}//*/
foreach(shape; shapes) { // Initialize rotate
shape.rotate(açı, Boyut.X);
shape.rotate(açı, Boyut.Y);
shape.rotate(açı, Boyut.Z);
}
}
void Draw() {
with(window.draw) {
clear(backgroundColor);
SetOrigin(Point(windowWidth/2, windowHeight/2));
foreach(shape; shapes) {
shape.rotate(açı, Boyut.Y);
shape.transform();
/*
outlineColor = Color.red;
fillColor = Color.red;
foreach(point; shape.nodes) {
drawCircle(
Point(cast(int)point.x-2, cast(int)point.y-2), 4
);
}//*/
foreach(point; shape.kenar) {
point.XY.writeln(", ", point.EB);
outlineColor = point.rengi;
drawLine(point.XY, point.EB);
}
}
}
}
}
class Shape {
Nodes[9] nodes;
this(Nodes p, double b) {
auto boyut = Nodes(b, b, b);
nodes[0] = Nodes(p.x - boyut.x, p.y - boyut.y, p.z - boyut.z); // A1 Köşesi (-)(-)(-)
nodes[1] = Nodes(p.x - boyut.x, p.y - boyut.y, p.z + boyut.z); // B1 Köşesi (-)(-)(+)
nodes[2] = Nodes(p.x - boyut.x, p.y + boyut.y, p.z - boyut.z); // A0 Köşesi (-)(+)(-)
nodes[3] = Nodes(p.x - boyut.x, p.y + boyut.y, p.z + boyut.z); // B0 Köşesi (-)(+)(+)
nodes[4] = Nodes(p.x + boyut.x, p.y - boyut.y, p.z - boyut.z); // D1 Köşesi (+)(-)(-)
nodes[5] = Nodes(p.x + boyut.x, p.y - boyut.y, p.z + boyut.z); // C1 Köşesi (+)(-)(+)
nodes[6] = Nodes(p.x + boyut.x, p.y + boyut.y, p.z - boyut.z); // D0 Köşesi (+)(+)(-)
nodes[7] = Nodes(p.x + boyut.x, p.y + boyut.y, p.z + boyut.z); // C0 Köşesi (+)(+)(+)
nodes[8] = Nodes(p.x, p.y, p.z); // Şeklin Merkezi
}
void ekseniDöndürüpUyarla(Boyut eksen) {
rotate(açı, eksen);
transform();
}
void rotate(int angle, Boyut dimension) {
auto angleTheta = cast(double)angle;
Nodes cosTheta, sinTheta;
foreach(ref node; nodes) {
if(dimension == Boyut.X || dimension == Boyut.Z) {
cosTheta.x = node.x * cos(angleTheta);
sinTheta.x = node.x * sin(angleTheta);
}
if(dimension == Boyut.Y || dimension == Boyut.Z) {
cosTheta.y = node.y * cos(angleTheta);
sinTheta.y = node.y * sin(angleTheta);
}
if(dimension == Boyut.X || dimension == Boyut.Y) {
cosTheta.z = node.z * cos(angleTheta);
sinTheta.z = node.z * sin(angleTheta);
}
if(dimension == Boyut.X) {
node.x = cosTheta.x + sinTheta.z;
node.z = cosTheta.z - sinTheta.x;
}
if(dimension == Boyut.Y) {
node.y = cosTheta.y - sinTheta.z;
node.z = cosTheta.z + sinTheta.y;
}
if(dimension == Boyut.Z) {
node.x = cosTheta.x - sinTheta.y;
node.y = cosTheta.y + sinTheta.x;
}
}
}
abstract void transform();
abstract Çizgi[] kenar();
}
struct Çizgi {
Point XY;
Point EB;
Color rengi;
this(Nodes XY, Nodes EB, Color c) {
this.XY.x = cast(int)XY.x;
this.XY.y = cast(int)XY.y;
this.EB.x = cast(int)EB.x;
this.EB.y = cast(int)EB.y;
this.rengi = c;
}
}
class Tetrahedron : Shape {
Çizgi[6] edges;
Color c;
this(Nodes konum, double boyut, Color c = Color.gray) {
super(konum, boyut);
this.c = c;
}
override void transform() {
edges[0] = Çizgi(nodes[5], nodes[6], c);
edges[1] = Çizgi(nodes[5], nodes[0], c);
edges[2] = Çizgi(nodes[5], nodes[3], c);
edges[3] = Çizgi(nodes[3], nodes[6], c);
edges[4] = Çizgi(nodes[6], nodes[0], c);
edges[5] = Çizgi(nodes[0], nodes[3], c);
}
override Çizgi[] kenar() { return edges; }
}
class Polyhedron : Shape {
Çizgi[8] edges;
Color c;
this(Nodes konum, double boyut, Color c = Color.gray) {
super(konum, boyut);
this.c = c;
}
override void transform() { // 8 Çizgi
edges[0] = Çizgi(nodes[2], nodes[8], c); // A Köşesi (dikmesi)
edges[1] = Çizgi(nodes[3], nodes[8], c); // B Köşesi (dikmesi)
edges[2] = Çizgi(nodes[7], nodes[8], c); // D Köşesi (dikmesi)
edges[3] = Çizgi(nodes[6], nodes[8], c); // D Köşesi (dikmesi)
edges[4] = Çizgi(nodes[2], nodes[3], c); // A Kenarı (A0)
edges[5] = Çizgi(nodes[3], nodes[7], c); // B Kenarı (B0)
edges[6] = Çizgi(nodes[7], nodes[6], c); // C Kenarı (C0)
edges[7] = Çizgi(nodes[6], nodes[2], c); // D Kenarı (D0)
}
override Çizgi[] kenar() { return edges; }
}
class Cube : Shape {//, IShape {
Çizgi[12] edges;
Color c;
this(Nodes konum, double boyut, Color c = Color.gray) {
super(konum, boyut);
this.c = c;
}
override void transform() { // 12 Çizgi
edges[0] = Çizgi(nodes[0], nodes[1], c);
edges[1] = Çizgi(nodes[1], nodes[5], c);
edges[2] = Çizgi(nodes[5], nodes[4], c);
edges[3] = Çizgi(nodes[4], nodes[0], c);
//*toogle-switch for perpendiculars/
edges[4] = Çizgi(nodes[2], nodes[0], c);
edges[5] = Çizgi(nodes[3], nodes[1], c);
edges[6] = Çizgi(nodes[7], nodes[5], c);
edges[7] = Çizgi(nodes[6], nodes[4], c);
//toogle-switch perpendiculars*/
edges[8] = Çizgi(nodes[2], nodes[3], c);
edges[9] = Çizgi(nodes[3], nodes[7], c);
edges[10] = Çizgi(nodes[7], nodes[6], c);
edges[11] = Çizgi(nodes[6], nodes[2], c);
}
override Çizgi[] kenar() { return edges; }
}
alias Painter = PainterHelper;
void main() {
auto rnd = Random(41);
auto scr = new Painter(windowWidth, windowHeight, "Shapes 3D", Color.white);
with(scr) window.eventLoop(fps, &Draw,
delegate (KeyEvent event)
{
if(event.key == Key.Space)
{
auto rasgele = uniform(0, shapes.length);
shapes[rasgele].ekseniDöndürüpUyarla(Boyut.X);
}
else if(event.key == Key.Escape)
{
window.close();
}
}
);
}
Not: Boşluk tuşuna basıp rasgele şekilleri ekstra döndürmeniz mümkün.