AS3 - geometry - perspective projection of a point on a 2D plane

I am currently struggling with a problem that seems far beyond the scope of my mathematics (I have not studied mathematics for a long time ...), and I would appreciate help in this.

Here is my setup: I have simple shapes (rectangles), and I "project" their lower points onto the line coming from the Origin point. Up to this point, everything is in order. But now I would like to draw the original shape, distorted, as if it were projected with some perspective on the plane.

Please note that I have nothing to do with any kind of rotation, isometric or some kind of three-dimensional or fake 2D representation in my code, I am only trying to draw some shapes using the graphics library in order to have only something real .

Here is a brief picture of what I'm trying to do:

enter image description here

What i know:

  • Origin point coordinates
  • rectangle location and size
  • red line position
  • coordinates of points A and B

What I want to determine is the coordinates of points C and D , which can be easy if I do not try to find the coordinates of "Origin bis".

What I'm trying to do is fake the projection of my rectangle onto something that can be thought of as a “floor” (referring to the plane where my original rectangle is a wall).

Maybe I'm complicating the problem too much, or maybe I don't see any other easier way to do this, but I'm really not very good at any geometry or math ...: - (

Thanks so much for your answers!

+6
source share
3 answers

hmm I don’t know if I understood correctly, but I think that you have too few input parameters:

You said the following information:

  • Origin point coordinates
  • rectangle location and size
  • red line position
  • coordinates of points A and B

I don’t think you can get your projection rectangle with just this information. In addition, I think your green lines and the “Bis source” also do not help.

Perhaps try this: Suppose the blue line passes through points C and D. Then you can find the projected rectangle by projecting the top of the rectangle onto this blue line.

So, in short: You define the beginning + two parallel lines, red and blue. Then you can project the top of the rectangle onto the blue line and the bottom of the rectangle onto the red line, getting points A, B, C, D

Hope this helps.

0
source

If I'm right, this code will show what you wanted to see.

First of all, I ignored your initial setup of objects and information and focused on the situation of the example itself; fake shadow projection for a “monolith” (any object is possible with the example below, even textured) My reason was that it was really quite easy with the Matrix ActionScript class, a handy tool worth exploring.

Solution: You can use the built-in Matrix class to convert a slash to DisplayObject s. Try this example:

(The "useful" part is in the _EF EnterFrame handler;))

 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 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; } 

Now all you need to know to use this in your case is the following N factors:
Q1: From what angle do you want to project the shadow?
A1: the horizontal coefficient is the skew variable itself, while the vertical angle is stored here as a constant called MAX_SHADOW_HEIGHT_MULTIPLIER

Q2: Do you want to design the shadow only "up" or freely? A2: if the “up” is ok, keep the skew in the positive range, otherwise let it take negative values ​​also for the shadow “down”

PS: if you render internal objects that they don’t snap to 0 y as a base point, you can make them seem like float / sink or move both objects vertically with a predefined value, with the opposite sign.

0
source

You are faced with one very simple problem, as you said:

'I want to determine the coordinates of points C and D, which can be easy if I do not try to find the coordinates of "Origin bis".

But these coordinates are related to each other, so without one (or another value, such as an angle) you cannot have another. If you try it in 3D, you just let the 3D engine define the "Origin bis" and do the calculations for C and D itself.

So, regardless of whether you need an “Original Encore,” another value that refers to the red line or your Rect, for which you can calculate the placement of C and D.

I remember how this was done, and sometimes it’s better to just keep it simple, you either define the “Original Encore” (it can be either stationary or move along with the player / background) and get C and D you have A and B only that you use the bottom line than the red line, or, as I would do, after you have A and B, just skew / rotate your projection from these points a little further, and you will get something the same like the "Original Encore" that follows the player. This works great when modeling a “sensation of something real,” but, unfortunately, it has been said to look real, depending on what you are portraying. We don’t know which areas are above or below the red line (sky / earth, earth / water) and whether Origin and Origin bis are your light source, vanishing point, etc.

0
source

Source: https://habr.com/ru/post/927366/


All Articles