Find Upper Right Point of Rotated Rectangle in AS3 (Flex) - apache-flex

I have a rectangle of any arbitrary width and height. I know X,Y, width, and height. How do I solve the upper right hand coordinates when the rectangle is rotated N degrees? I realized if it were axis aligned I would simply solve for (x,y+width). Unforunatly this doesn't hold true when I apply a transform matrix on the rectangle to rotate it around its center.

It's usually easiest and fastest to let Flash's display code do these kinds of things for you. Create an empty Sprite and put it inside the rectangle's display object at the corner you want to track. Then, find the location of that sprite in the coordinate space of your choice:
var p:Point = new Point(0,0);
myRectangle.myCornerSprite.localToGlobal( p );
someDisplayObject.globalToLocal( p ); // for a coord space besides the stage
This gets you out of making any assumptions about the rectangle's design (i.e. registration point), and works even if the rectangle should be skewed or scaled as well as being rotated. Plus, this will be much easier to implement and maintain then a mess of cosines and whatnot.
(Note that the code above assumes that "upper right" refers to a specific corner - if you want to examine whichever corner happens to upper-rightmost at the moment, I'd simply add do the same thing with a sprite at all four corners, and pick whichever is to the upper right in global coords.)

You just have to calculate the point on a circle for the given radius. The center of your rectangle will be the circle's origin and any corner will be a point on the circle's circumference. You need to use trigonometry to calculate the new point using the rotation. I don't have time right now to explain all this, but here is a link to a decent 2D Javascript library I've used in the past and which should give you everything you need (bearing in mind that the math is virtually the same in Javascript and ActionScript) to work it out for yourself.
http://jsdraw2d.jsfiction.com/viewsourcecode.htm

Related

Aframe Checkpoints and camera view

I'm using aframe for a VR project I'm doing and I'm using checkpoint on the ground to lead the user around the 3D space. I received help before on how to create a checkpoint here
Here is the link to the most current iteration of my project -> https://museum-exhibit-demo.glitch.me/webVR.html
Is it possible to have the animation that takes you to the cylinder also change the view of the camera and height? Basically once I click the cylinder to take me to the position it will also snap my view to the text on the wall even if it is not eye height
Great Demo. I've prepared a candidate solution on glitch (app). This solution changes the height of the camera, and the horizontal direction/yaw of the camera. It does not change the pitch of the camera. Ideally any AR/VR app would minimise forcing a change of camera orientation. If you forcibly change the pitch of the camera that's like permanently tilting the floor of the user. If you just change the yaw then that just permanently changes the horizontal direction they are look. Changing the pitch can be done, but I think from a user perspective that might cause more problems than it is worth, changing the yaw is just about OK. Similar recommendations were previously mentioned in https://stackoverflow.com/a/47667912/10849562.
I'll break down the solution code by how it solves your two issues, to have the animation that takes you to the cylinder also change the height of the camera, and separately how it can change the view/direction? I'll add in line references to the solution were relevant.
Change the height to match the height of the text
First you need to know the height of the text associated with the checkpoint cylinder. One way to do this is to provide the id of the related a-text entity to the goto component. To do that I added a new component property textId to your goto component (L79). Then in each of the places where you have used the goto component the textId property was set. For example for the checkpoint cylinder associated with the Welcome! text, the goto component was changed to goto="textId: welcome" (L298).
The id of the associated a-text enitity can be accessed from methods of the goto component using this.data.textId which will be different for each goto component. Using this information within the component, the position of the a-text enitity can be found in a similar way to how you found the rig position, by finding the a-text element with document.querySelector L83 and then finding the position L93.
let text = document.querySelector(`#${this.data.textId}`);
text.object3D.getWorldPosition(textPos);
Note that instead of using text.getAttribute("position") the getWorldPosition method is used instead. That is because you have wrapped your a-text elements inside a-entity elements that also have positions set. getAttribute("position") only gives you the position relative to its parent entity, but this solution requires the absolute/world position of the text. Of course other solutions might do things different, and it's also possible to change the HTML structure of your demo so that you could use getAttribute("position"). getWorldPosition is a method from THREE.js (which A-Frame is based on) and stores the position in the textPos variable. You can use textPos in the same way as rigPos. Instead of rigPos.y you can now do textPos.y to get the height of the text as the end point of the position animation to change the height of the camera.
Note that 1.6 is taken away from the height in the solution. The default height of the camera in A-Frame is 1.6. You've handled this by reducing the position of the camera by -1.1 in the #pov entity.
Change the direction of the camera match the direction of the text
First we need to know the direction of the text with respect to its associated checkpoint cylinder. Because we now have access to the position of the cylinder the direction vector between from the cylinder to the text can be calculated (L111). From this the azimuthal angle or yaw angle of the direction from the checkpoint cylinder to the text can be calculated (L115). To do this calculation a function getYaw was created (L46) to calculate the yaw angle.
Because you have already applied a yaw rotation of 90 degrees on your #pov entity that wraps your a-camera entity, the yaw angle is calculated from the negative z-axis (0, 0, -1).
Now that you have the direction the text is from the checkpoint cylinder, you need to know the yaw direction the camera is currently pointing in. You can find this out from the rotation component of the a-camera entity. Just like finding the position of any entity, you can find the a-camera element with document.querySelector (L84) and the find its yaw angle camera.getAttribute("rotation").y (L116). You can then calculate the target yaw angle that you should set the rig to by calculating the relative angle from the camera entity to the text entity which is called targetRigYaw in the solution (L117).
Note that there are lots of applications of a mod function. This simply ensures that all yaw angles are always positive and between [0, 360] which helps simplify things when applying angles.
You could now use the targetRigYaw as the angle to set your rig to to change the view direction to look at the text. However depending on the yaw angles of the text direction and camera direction, this angle might be greater than 180 degrees. You can imagine that you could rotate left or right to end up looking in a particular direction. Unless the direction you would like to look in is directly behind you, one of the direction will be a shorted rotation than the other. L120-123 change the targetRigYaw angle so that you are always rotating in the shortest angular direction to end up looking at the text.
In order to animate the yaw in the same way as you animated the position you can add second component to the #pov entity. In the solution this is called animation__rotation (L144). The A-Frame docs describe how you can add multiple animation using the __ notation https://aframe.io/docs/1.0.0/components/animation.html#multiple-animations.
We can then set the animation__rotation component to perform an animation of the rotation of the #pov entity in a similar way to the position. The animation__rotation component is set using setAttribute to rotate from the current yaw angle of the rig to the targetRigYaw angle, and the duration of the animation is set to the same length as the position animation.
I hope this helps solve your two questions. Please let me know if you have any questions. I've added comment to the code, however there were quite a few snippets that I added that might not be obvious what they do.

Translation of rotated element

I have an object rotated around point (0,0). I can't change the anchor point. The rotation is done by another system and I can't influence that. All I have control of is the position of the element (and I can access the rotation value).
Now, I'd like to adjust the element position to make it appear like it's rotating around a specific pivot point.
How it is:
How I want it to be:
I could be wrong (your description honestly isn't great) but it looks to me like you just want to have the anchor point (that you have no control over) in the center of your image. So you just need to know the anchor point, and then calculate, probably, the top-left corner of your image based on the center of it being at the same point as the anchor. If the anchor point is (a,b), the width and height of your image are w and h, respectively, then the top-left corner of your image should go at the point (a - w/2, b - h/2). That is you need to subtract off half of both dimensions.

How to get absolute coordinates with QGraphicsScene?

Let's say I have five objects, with the top-left red square and the larger black square both inserted into the scene at 0,0.
.
Later, let's say I want to move the bottom right corner of the black square to the bottom right corner of the bottom-right square. The most obvious thing to do would be:
bS.setRect( bS.rect().setBottomRight(redBR.rect().bottomRight) );
That's not exactly correct code, but the idea is simple. I would set the coordinate of the black square's bottom right corner to that of the red square's bottom right corner. Because that's where I want it to be. But in Qt, this seems to be impossible.
Because the call to redBR thinks it's at the origin. Every item thinks it's at the origin. Which means I can never know the coordinates of any item, anywhere, ever.
Is there a way to force QGraphicsScene to tell me the actual coordinates? Alternatively, is there some other graphics framework that uses real coordinates? I'm not going to insist on using Qt if there is no way to make it work.
Any help would be welcome. Please bear in mind my goal is not: "drag corner of box by manipulator". My goal is to be able to put items at coordinates whenever I want an item to be at a specific coordinate.
Edit:
Here's an example of what I mean. The big box hasn't been connected yet, so don't worry about it's coordinates. The problem is that if I don't remap the points coming out of the little box, every box believes it is at the origin. But if I do, then the y values vacillate between 0, 1, and -1.
The base class QGraphicsItem has quite some useful functionality for mapping between scene and item coordinates. One useful function is for mapping a point in item coordinates to scene coordinates:
QPointF QGraphicsItem::mapToScene(const QPointF &point)
There is however also a direct mapping available between points in different QGraphicsItems, which is probably the easiest to use here:
QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point)
which can be used to map a point in redBR to a point in bS like:
bS.rect().setBottomRight(bS.mapFromItem( &redBR, redBR.rect().bottomRight() ) )

How to understand CSS Background-Position coordinates

Every time I create a sprite to use as css background-image, I have to crunch the math and remind myself how to remember the X and the Y coordinates in pixels. How can I remember it or see it visually to keep it straight?
I came up with this graphic, hope it's helpful to someone else as well.
Think 'Y' rhymes with 'SKY' so thats your top measurement (distance in px) from the top. That leaves 'X' as the remaining distance (distance from left in pixels)
When I say distance from left and distance from top, I am referring to the distance in pixels from the side of your overall image to when the part you want to show, begins.
I usually keep the images anywhere on the Sprite sheet and then check out there co-ordinates by clicking on each graphic element in Fireworks(i use fireworks) and then negating the co-ordinates. For eg:if an element is at x=23px and y=20px, then in the CSS, i use background-position:-23px -20px. This always does the work.

How to set webkit-transform-origin to roll 3D cube on its edges?

I am fiddling around with CSS3 perspectives & transformations. Starting from this great 3D cube example, I would like to modify the cube such that it does not just rotate around its center, but roll over its edges.
I got the first left tilt working by rotating the cube around the z-axis, with -webkit-transform-origin: bottom left (see fiddle; example limited to left tilts for simplicity). For a subsequent left tilt, I am struggling how to further adjust the origin. Conceptually, I would need to set the origin relative to the parent container (i.e. for consecutive left tilts, it should gradually wander to the left in 200px steps).
Any help is greatly appreciated!
I've had a go at this and I think you'll need to look into the css matrix transformations available to you to get exactly what you want.
Unfortunately it's not as simple as rotate, then move transform origin.
What happens is the cube is rotated around that edge, but then if you move the point of transform it applies the previous transform to the cube using this new point of origin.
What's more you need to also translate the position of the cube. You can't move it along purely using rotations.
Matrices should solve all of this I think (I don't know an awful lot about them I'm afraid)
You can see the modified jsfiddle I created where the cube is rotated and translated.
The point of translation is the center though, so it doesn't look like the cube is "rolling".
here's the crucial extra code:
...
//left
zAngle -= 90;
xPos -= 50;
//rotate and translate the position of the cube
$('#cube')[0].style["WebkitTransform"]="translateX("+xPos+"px) rotateZ("+zAngle+"deg)";
...
js Fiddle here: http://jsfiddle.net/DigitalBiscuits/evYYm/20/
Hope this helps you!
I think this tutorial may help you.
http://desandro.github.io/3dtransforms/docs/cube.html
If you want to roll over its edges, just rotateZ and translateX. but how fast you want rotate, you may have to caculate it.
http://desandro.github.io/3dtransforms/examples/cube-02-show-sides.html

Resources