我试图找到将(x,y,z)翻译成(x,y)所需的数学,这样我就可以用php创建框了。所有点都将在网格上,并且没有旋转。
我已经尝试过这个解决方案https://stackoverflow.com/a/25955134/379249,它让我在那里的一部分,但我需要弄清楚多边形的点
例如,我有一个大框,下面显示为红色。
我需要能够给它宽度,长度,高度和起点的尺寸,或者我可以给出构成每张脸的所有四个点。
我需要翻译那些让它看起来像是我绊倒的3D。
创建红色框后,我还需要能够使用相同的功能创建其他框,例如绿色,蓝色或橙色框。
我可以创建代码,但我仍然坚持数学来进行翻译。
有什么想法吗?
谢谢!
编辑 **
感谢@ user2464424,我能够非常接近。以下是我的代码。
我生成的图像。
<?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">
一些问题。
1:如何在底部获取轴的原点,现在它在右侧颠倒。
2:假设我总是希望在400x400图像上制作它,我怎么能确保它不会消失或者能够放大?
3:如果容器是40x40x40或10x100x100,我怎样才能调整原点,使其始终位于图像的底部,并且框会缩放以适合?
编辑 **
以下是最终代码的链接: https://gist.github.com/rzfarrell/3a9e5046dcfd6bd2d2f4bfa1a34b21ef
答案 0 :(得分:1)
在3D空间中3D点对照自由相机的正投影的主要思想是移动和旋转相机,使其最终成为a)以原点为中心,b)不旋转。问题在于,构成3D世界的所有点必须严格遵循相机的变换。
这通常归结为两个步骤:
1)首先,通过反转的原点相机矢量转换点:
$x = $pointx - $camx; $y = $pointy - $camy; $z = $pointz - $camz;
2)然后,通过相机的俯仰和偏转角度(可能以弧度为单位)旋转原点周围的点:
$sy = sin(-$yaw); $cy = cos(-$yaw); $sp = sin(-$pitch); $cp = cos(-$pitch);
function RotatePoint($sin,$cos,$x,$y) {
return array($x*$cos - $y*$sin, $y*$cos + $x*$sin);
}
$rot = RotatePoint($sy,$cy,$x,$y);
$x = $rot[0];
$y = $rot[1];
$rot = RotatePoint($sp,$cp,$z,$y);
$z = $rot[0];
$y = $rot[1];
你完成了。现在,$x
和$z
表示相机平面中距离相机中心的2D点的坐标,$y
是该点与相机平面的垂直距离。
如果要输出图片,可能需要缩放并限制坐标以适合图像尺寸,这是微不足道的。你必须考虑的一件事是忽略所有y<=0
点,因为这意味着它们在镜头后面。