Ich versuche die Mathematik zu finden, die benötigt wird, um (x, y, z) in (x, y) zu übersetzen, damit ich Boxen mit PHP erstellen kann. Alle Punkte sind am Gitter und es gibt keine Rotationen.3D-Objekt auf 2D-Raum übersetzen
Ich habe diese Lösung https://stackoverflow.com/a/25955134/379249 ausprobiert, die mir dort einen Teil des Weges kommt, aber ich brauche die Punkte der Polygone, um herauszufinden,
Zum Beispiel habe ich eine große Kiste unten in rot dargestellt.
Ich brauche es, die Abmessungen von entweder Breite, Länge, Höhe und Ausgangspunkt in der Lage zu geben, oder kann ich es alle vier Punkte geben, die jedes Gesicht.
Ich muss diese übersetzen, damit es 3D erscheint, worüber ich gestolpert bin.
Sobald die rote Box erstellt wurde, müsste ich auch in der Lage sein, andere Boxen mit der gleichen Funktion wie die grüne, blaue oder orange zu erstellen.
Ich kann den Code erstellen, aber ich bin auf der Mathematik fest, um die Übersetzungen zu tun.
Irgendwelche Ideen?
Danke!
EDIT **
Dank @ user2464424 ich in der Lage bin, um es ganz in der Nähe zu bekommen. Unten ist mein Code.
Und mein generiertes Bild.
<?php
function RotatePoint($sin,$cos,$x,$y) {
return array($x*$cos - $y*$sin, $y*$cos + $x*$sin);
}
$im = imagecreatetruecolor(200, 200);
$white = imagecolorallocate($im, 255, 255, 255);
imagefilledrectangle($im, 0, 0, 200, 200, $white);
$brown = imagecolorallocate($im, 120, 53, 31);
$green = imagecolorallocate($im, 23, 255, 65);
$blue = imagecolorallocate($im, 31, 23, 255);
$orange = imagecolorallocate($im, 255, 185, 23);
function draw_box(&$image, $color, $start, $width, $length, $height)
{
$camx = 80;
$camy = 240;
$camz = 40;
$yaw = 10;
$pitch = 20;
$sy = sin(-$yaw); $cy = cos(-$yaw); $sp = sin(-$pitch); $cp = cos(-$pitch);
$start_x = $start[0];
$start_y = $start[1];
$start_z = $start[2];
// Draw 6 faces
for ($i = 0; $i < 6; $i++)
{
switch ($i)
{
case 0:
$face = array(
array($start_x, $start_y, $start_z),
array($start_x+$width, $start_y, $start_z),
array($start_x+$width, $start_y, $start_z+$height),
array($start_x, $start_y, $start_z+$height)
);
break;
case 1:
$face = array(
array($start_x, $start_y+$length, $start_z),
array($start_x+$width, $start_y+$length, $start_z),
array($start_x+$width, $start_y+$length, $start_z+$height),
array($start_x, $start_y+$length, $start_z+$height)
);
break;
case 2:
$face = array(
array($start_x, $start_y, $start_z),
array($start_x, $start_y+$length, $start_z),
array($start_x, $start_y+$length, $start_z+$height),
array($start_x, $start_y, $start_z+$height)
);
break;
case 3:
$face = array(
array($start_x+$width, $start_y, $start_z),
array($start_x+$width, $start_y+$length, $start_z),
array($start_x+$width, $start_y+$length, $start_z+$height),
array($start_x+$width, $start_y, $start_z+$height)
);
break;
case 4:
$face = array(
array($start_x, $start_y, $start_z+$height),
array($start_x+$width, $start_y, $start_z+$height),
array($start_x+$width, $start_y+$length, $start_z+$height),
array($start_x, $start_y+$length, $start_z+$height)
);
break;
case 5:
$face = array(
array($start_x, $start_y, $start_z),
array($start_x+$width, $start_y, $start_z),
array($start_x+$width, $start_y+$length, $start_z),
array($start_x, $start_y+$length, $start_z)
);
break;
}
$polygon = array();
foreach ($face as $point)
{
$x = $point[0] - $camx;
$y = $point[1] - $camy;
$z = $point[2] - $camz;
$rot = RotatePoint($sy,$cy,$x,$y);
$x = $rot[0];
$y = $rot[1];
$rot = RotatePoint($sp,$cp,$z,$y);
$z = $rot[0];
$y = $rot[1];
$polygon[] = $x;
$polygon[] = $z;
}
imagepolygon($image, $polygon, 4, $color);
}
}
draw_box($im, $brown, array(0, 0, 0), 80, 80, 80);
draw_box($im, $green, array(0, 0, 0), 40, 40, 40);
draw_box($im, $blue, array(0, 0, 40), 30, 20, 10);
draw_box($im, $orange, array(60, 0, 0), 15, 40, 80);
imagepng($im, './image.png');
imagedestroy($im);
?>
<img src="image.png">
Ein paar Fragen.
1: Wie bekomme ich den Ursprung der Achse unten, jetzt ist es auf dem Kopf nach rechts.
2: Soll ich es immer auf einem 400x400 Bild produzieren, wie würde ich sicherstellen, dass es nicht geht oder in der Lage zu skalieren?
3: Wenn der Container 40x40x40 oder 10x100x100 ist, wie kann ich den Ursprung so einstellen, dass er immer am unteren Rand des Bildes liegt und die Box skaliert?
EDIT **
Hier ist ein Link auf den endgültige Code: https://gist.github.com/rzfarrell/3a9e5046dcfd6bd2d2f4bfa1a34b21ef
Ich denke, was Sie versuchen zu erreichen ist orthographische Projektion, ist das richtig? – user2464424
Es gibt * bazillions * Möglichkeiten, 3D auf 2D zu projizieren. Wenn Sie noch nicht wissen, dann werfen Sie einen Blick auf: https://en.wikipedia.org/wiki/Graphical_projection. Übersetzungen sind auch einfach (nur x '= x + delta, etc.). Drehungen sind viel schwieriger: https://en.wikipedia.org/wiki/Rotation_(mathematics) –
@ user2464424 ja orthographische Projektion ist, was ich suche. – bones