AS3 - 几何 - 2D平面上某点的透视投影

时间:2012-10-10 15:20:56

标签: actionscript-3 math 3d geometry

我目前正在努力解决一个远远超出我数学能力的问题(很长一段时间以来,我已经做了一些正确的数学......)我会很感激一些帮助。

这是我的设置: 我有一些简单的形状(矩形),我"项目"他们的底线在一条线上,来自原点。 到目前为止,一切都很好。 但是现在我想把原来的形状画得扭曲,仿佛它是在平面上以一些透视投影的。

请注意我的代码中没有与旋转,等距或任何3D或假2D视角相关的内容,我只是尝试使用图形库绘制一些形状,只有感觉<真实的东西。

这里是我想要做的事情的快速绘图:

enter image description here

我所知道的:

  • 原点坐标
  • 矩形位置&amp;大小
  • 红线位置
  • A&amp; B点坐标

我想要确定的是C&amp; C的坐标。 D点,如果我没有努力找到&#34; Origin bis&#34;坐标。

我想要做的就是将我的矩形的投影伪装成可被视为&#34; floor&#34; (与我原来的矩形可以看作墙的平面相关)。

也许我过度复杂化了问题,或者我没有看到任何其他更容易的方法,但我在任何几何或数学方面都不再好...... : - (

非常感谢您的回答!

3 个答案:

答案 0 :(得分:0)

嗯,我不知道我是否正确地取消了它,但我认为你的输入参数太少了:

你说的是以下信息:

  • 原点坐标
  • 矩形位置&amp;大小
  • 红线位置
  • A&amp; B点坐标

我认为不可能仅使用此信息来获取投影矩形。 另外,我认为你的绿线和'起源Bis'也没有帮助。

也许,试试这个: Supose,穿过C&amp;点的蓝线D也被给出。 然后,您可以通过将矩形的顶部投影到该蓝线上来找到投影的矩形。

总结如下: 您定义原点+两条平行线,红色和蓝色。 然后你可以将矩形顶部投影到蓝线上,将矩形底部投影到红线上,得到点A,B,C,D

我希望这会有所帮助。

答案 1 :(得分:0)

如果我是对的,此代码将显示您想要查看的内容。

首先,我忽略了对象和信息的初始设置,并专注于示例情境本身;用于“巨石”的假投影阴影(任何对象都可以使用下面的示例,甚至纹理化) 我的理由是使用Matrix类ActionScript非常容易,这是一个值得学习的便利工具。

解决方案: 您可以使用内置的Matrix类对DisplayObject进行偏斜变换。 试试这个例子:

(“有用”部分位于_EF EnterFrame处理程序;))

import flash.display.MovieClip;
import flash.geom.Matrix;
import flash.events.Event;
import flash.display.BitmapData;

const PIP180:Number = Math.PI / 180;
const MAX_SHADOW_HEIGHT_MULTIPLIER:Number = 0.25; // you can also calculate this from an angle, like ... = Math.sin(angle * PIP180);
const ANIM_DEG_PER_FRAME:Number = 1.0 * PIP180; // the shadow creeps at a +1 degree per frame rate

var tx:BitmapData = new MonolithTexture(); // define this BitmapData in the library
var skew:Number = -10 * PIP180; // initial 

var mono:MovieClip = new MovieClip();
mono.graphics.beginBitmapFill(tx);
// drawn that way the registration point is 0,0, so it's standing on the ground
mono.graphics.drawRect(0, -tx.height, tx.width, tx.height);
mono.graphics.endFill();

// align monolith to the "ground"
mono.x = stage.stageWidth / 2;
mono.y = stage.stageHeight - 100;
// make it be 100x300 pixel
mono.width = 100;
mono.height = 300;

var shad:MovieClip = new MovieClip();
// colored:
shad.graphics.beginFill(0x000000);
// or textured:
//shad.graphics.beginBitmapFill(tx);
shad.graphics.drawRect(0, -tx.height, tx.width, tx.height);
shad.graphics.endFill();

addChild(shad); // shadow first
addChild(mono); // then the caster object

addEventListener(Event.ENTER_FRAME, _EF);

function _EF(e:Event):void {
    // animate skew on the positive half circle
    skew = (skew + ANIM_DEG_PER_FRAME) % Math.PI;

    // Matrix takes 6 parameters: a, b, c, d, x, y
    // for this shadow trick, use them as follows:
    // a = width scaling (as mono and shad are drawn in the same way, copy mono.scaleX for a perfect fit
    // b = 0, because we don't want to project the vertical axis of transformation to the horizontal
    // c = horizontal skew
    // d = height scaling * skew * making it a bit flat using the constant
    // x = mono.x, ...
    // y = mono.y since originally mono and shad look alike, only the Matrix makes shad render differently
    var mtx:Matrix = new Matrix(mono.scaleX, 0, Math.cos(skew), mono.scaleY * Math.sin(skew) * MAX_SHADOW_HEIGHT_MULTIPLIER, mono.x, mono.y);
    shad.transform.matrix = mtx;
}

现在你要知道在你的情况下利用这个,是以下N个因素:
Q1:你想从什么角度投影阴影?
A1:水平因子本身是skew变量,而垂直角度在这里存储为常量,称为MAX_SHADOW_HEIGHT_MULTIPLIER

Q2:您是否只想“向上”或自由地投影阴影? A2:如果“向上”是好的,请将skew保持在正范围内,否则让它为负向值以获得“向下”阴影

PS:如果渲染它们没有捕捉到0 y的对象的内部作为基点,你可以使它们看起来像浮动/下沉,或者用预定义的值垂直偏移两个对象,符号相反

答案 2 :(得分:0)

你面临一个非常简单的问题,正如你所说:

'我想要确定的是C&amp; C的坐标。 D点,如果我没有努力找到“Origin bis”坐标,那可能很容易。

但是这些坐标彼此相关,所以没有一个(或角度等其他值)你不能拥有另一个。如果您要在3D中尝试此操作,您只需允许3D引擎定义“Origin bis”并对C和D本身进行计算。

因此,无论你需要一个'原始二进制',另一个与红线或你的矩形相关的值来计算C和D的位置。

我记得制作这样的东西,有时最好坚持简单,你要么自己定义'原创之二'(它可以是静止的,也可以随播放器/背景一起移动)并获得C和D你得到A和B只是因为你使用的线条比红线低,或者就像我想的那样,一旦你有A和B,简单的歪斜/旋转你的投影从那些点下来一点点,你得到的东西与玩家之后的“原始之二”相同。这可以很好地模拟“真实的感觉”,但遗憾的是,它看起来真实,取决于你的描绘。我们不知道红线上方或下方的区域是什么(天空/地面,地面/水)以及“原点”和“原点之二”是您的光源,消失点等。