7

我目前正在努力解决一个似乎远远超出我的数学能力的问题(自从我做了一些适当的数学以来已经很长时间了......),我希望能得到一些帮助。

这是我的设置:我有一些简单的形状(矩形),我将它们的底点“投影”在一条线上,来自一个原点。到目前为止,一切都很好。但是现在我想绘制扭曲的原始形状,就好像它是在平面上以某种透视投影的一样。

请考虑我的代码中与任何旋转、等距或任何 3D 或假 2D 透视无关,我只是尝试使用图形库绘制一些形状,只是为了感受真实的东西。

这是我正在尝试做的快速绘图:

在此处输入图像描述

我知道的 :

  • 原点坐标
  • 矩形位置和尺寸
  • 红线位置
  • A & B 点坐标

我想确定的是 C & D 点的坐标,如果我不努力寻找“Origin bis”坐标,这很容易。

我正在尝试做的是伪造我的矩形投影在可以被视为“地板”的东西上(与我的原始矩形所在的平面相关,可以看作是一堵墙)。

也许我把问题复杂化了,或者我看不到任何其他更简单的方法,但我在任何几何或数学方面真的不擅长了...... :-(

非常感谢你的回答 !

4

3 回答 3

0

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

“我想要确定的是 C&D 点的坐标,如果我不努力寻找“Origin bis”坐标的话,这很容易。”

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

因此,无论您是否需要“原始之二”,与红线或您的 Rect 相关的另一个值,用于计算 C 和 D 的位置。

我记得制作这样的东西,有时最好坚持简单,你要么自己定义一个“原始之二”(它可以是静止的,也可以随着玩家/背景移动),然后按照你得到的方式获得 C 和 D A 和 B 只是你使用比红线更低的线,或者就像我会做的那样,一旦你有了 A 和 B,简单地将你的投影从这些点向下倾斜/旋转一点,你会得到相同的东西跟随玩家的“原始之二”。这在模拟“对真实事物的感觉”方面效果很好,但遗憾的是,正如已经说过的那样,它看起来真实取决于您所描绘的内容。我们不知道红线上方或下方的区域是什么(天空/地面,地面/水)以及“Origin”和“Origin bis”是否是您的光源、消失点等。

于 2013-06-07T09:36:22.310 回答
0

嗯,我不知道我是否正确理解了它,但我认为您的输入参数太少:

您说提供了以下信息:

  • 原点坐标
  • 矩形位置和尺寸
  • 红线位置
  • A & B 点坐标

我认为仅凭此信息无法获得投影的矩形。此外,我认为您的绿线和“原点之二”也没有帮助。

也许,试试这个:假设,一条穿过点 C 和 D 的蓝线也给出了。然后你可以通过将矩形的顶部投影到那条蓝线上来找到你的投影矩形。

总而言之:您定义了一个原点 + 两条平行线,一条红色和一条蓝色。然后你可以将矩形的顶部投影到蓝线上,将矩形的底部投影到红线上,产生点 A、B、C、D

我希望这有帮助。

于 2012-10-15T12:42:46.213 回答
0

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

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

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

(“有用”的部分在于 _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 作为基点的对象的内部,您可以使它们看起来浮动/下沉,或者使用预定义的值垂直偏移两个对象,使用相反的符号。

于 2013-01-23T15:53:12.527 回答