Is there a way to absolute position a view using position() in a single axis?
For example, I want to absolute position an element's x position but leave the y position as default.
Yes. Use .padding(.leading, 100). This will make the view have a 100 point gap on the left, but keep the Y position default.
Related
The problem didn't let me sleep at night.
Given floating point x and y coordinates of infinite 2D space, and the range variable, I need to get all possible intergrer coordinates that are in range.
The green blocks are in range, and the red ones are not.
Now, I have an answer, but I'm not sure if it's the best one.
Make an 2D array with all the values in a square around the point (from -distance, distance to distance, -distance) and then iterate through the entire array, each time checking the distance if it is closer or further than needed, and if so then insert it into another array.
Starting from the center point, go both ways horizontally to the furthest points that are in the range.
For each of these points encountered, calculate the maximum vertical coordinate either way which will still be in the range, and add all the squares along this line.
So in another question I was told that you could use a simplified formula of the dot product to find the angle between two vectors:
angle = atan2(mouseY, mouseX) - atan2(yPos, xPos); //xPos, yPos is position of player
Except, from what I understood it simply takes points as vectors. Which is why the mouse and player position is plugged in the parameters. However when I move the mouse around the player in a 360 degree radius, the angle and therefore rotation of the player is a value from around -0.3... to -1.4...
Is this not the correct method? Am I supposed to be representing vectors not as X, Y positions but as something else?
There's also another formula I found which also doesn't seem to work for me:
angle = atan2(mouseY - yPos, mouseX - xPos);
The first method is correct, the second is wrong. The function atan2(x,y) computes the angle in radians of a vector pointing from (0,0) to (x,y) with respect to the x-axis. It is thus correct to calculate two angles (in radians) the vectors have wih respect to the x-axis and then subtract these from each other to obtain the angles between the two vectors.
The result of the function atan2 is a value in the half-open interval (-pi,pi]. Expressed in degrees, this corresponds to (-180°,180°). 0° thereby denotes a vector pointing right (along the x-axis), 90° a vector pointing up, 180° a vector pointing left and -90° a vector pointing down.
You can transform the result in radians to angles via the formula
atan(x,y)*180/pi
So, if you want to transform your resulting values into angles, just multiply them by 180/pi.
In 2d space we have a collection of rectangles.
Here's a picture:
Vertical line on the right is non-moveable "wall".
Arrow on the left shows direction of movement.
I need to move leftmost rectangle to the right.
Rectangles cannot rotate.
Rectangles are not allowed to overlap horizontally.
Rectangle can shrink (horizontally) down to a certain minimum width (which is set individually to each rectangle)
Rectangles can only move horizontally (left/right) and shrink horizontally.
Leftmost rectangle (pointed at by arrow) cannot shrink.
Widths and coordinates are stored as integers.
I need to move leftmost rectangle to the right by X units, pushing everything in its way to the right.
There are two problems:
I need to determine how far I can move leftmost rectangle to the right (it might not be possible to move for X units).
Move rect by X units (or if it is not possible to move by X units, move by maximum possible amount, smaller than X) and get new coordinates and sizes for every rectangle in the system.
Additional complications:
You cannot use Y coordinate and height of rectangle for anything, instead
every rectangle has a list (implemented as pointers) of rectangles it will hit if you keep moving it to the right, you can only retrieve x coordinate, width, and minimum width. This data model cannot be changed. (technically, reppresenting this as a set of rectangles in 2d is simplification)
Important: Children from different levels and branches can have the same rectangle in the "potential collision" list. Here's initial picture with pointers displayed as red lines:
How can I do it?
I know a dumb way (that'll work) to solve this problem: iteratively. I.e.
Memorize current state of the system. If state of the system is already memorized, forget previously memorized state.
Push leftmost rect by 1 unit.
Recursively resolve collisions (if any).
If collision could not be resolved, return memorized state of the system.
If collisions could be resolved, and we already moved by X units, return current state of the system.
Otherwise, go to 1.
This WILL solve the problem, but such iterative solution can be slow if X is large. Is there any better way to solve it?
One possible solution that comes to mind:
You said that each rectangle holds pointers to all the objects it will hit when moving right. I would suggest, take the list of pointers from the big rectangle (the one pointed by the arrow), take all it's nodes (the rectangles it would collide), find the min width, then do the same of all the child nodes, add the widths for each branch recursively. Treat the problem like a tree depth problem. Every node has a min width value so the answer to your question would be the distance between the wall and the x value of the right edge of the big rectangle minus the GREATEST sum of the least width of the rectangles. Create a vector where the depth (sum of min widths) of each branch of the tree is stored and find the max value. Distance minus max is your answer.
imagine the same picture with 4 boxes. one to the left, one to the right and then the wall. lets name them box 1, box 2 (mid top), box 3 (mid bottom) and the last one box 4 (right). each box has a width of 4. all can shrink except the left one. box 2 can shrink by 2, box 3 can shrink by 1, box 4 can shrink by 2. Calculating the 2 branches gives
* Branch 1 : 2 + 2 = 4
* Branch 2 : 3 + 2 = 5
* Only concerned with branch 2 because branch 1 is LESS than branch 2 hence will fit in the space parallel to branch 2and is available to shrink that much.
In my program, I had a requirement to plot a rectangle that that is prependicular to a line coming from the centre.
To orient the rectangle in this way in 3D space, I used the gluLookAt giving it the lookAt point and plotted the rectangular figure. This worked correctly for me.
To draw the rectangle (in my framework, that uses openGL at the back), I now use a rectangle class and have extended it with a 3D Node (where node is something that has a lookAt point). Given width, height and the top vertex, the rectangle is drawn (node is at the top left vertex and orients the rectangle using lookAt).
Node also has a getPosition() function that gives me its 3D position (top left in rectangle - say 300,400,20). I am trying to get the position of the other three vertices in 3D space to use for my operation. Since the rectangle is oriented in 3D space, other three vertices can't just be fetched by addition of width and height. With the rectangle oriented in 3D, how do I get the position of the other three vertices?
The minimum amount of coordinates is just slightly less than 9: that's three vertices of a generic rectangle in 3d-space (Ax,Ay,Az, Bx,By,Bz, Cx,Cy,Cz).
The last one is e.g. D=A+(B-A)+(C-A)=B+C-A.
Why it's slightly less, is that any triplet of A,B,C coordinates do not necessarily form a 90 degree angle -- but it really doesn't make much sense to pursuit for the simplistic possible arrangement and be prepared to calculate cross-products or normalize vectors.
A----B
| |
C---(D)
EDIT: Vector arithmetic primary:
To Add / Subtract vectors, one sums the elements.
A=B+C means (ax = bx+cx; ay=by+cy; az=bz+cz).
Dot product in (any dimension) is the sum of product of terms:
dot(A,B) = ax*bx + ay*by + az*bz; // for 2,3,4, any number of elements/dimensions.
Cross product is a special operator that is well defined at least in 2 and 3 dimensions. One of the geometric interpretations of cross product is that it produces a vector that is perpendicular to both vectors of it's parameters.
If A is a vector (ax,ay,az), it also means a direction vector from origin O=(0,0,0) i.e. A = A-O = (ax-0,ay-0,az-0);
Likewise (B-A) is a [direction] vector from A to B (sometimes written as AB (with an arrow --> on top))
One can 'add' these directed vectors e.g. as:
o----->
\
\
<------o
/
/
x
And so, if one adds the vector A+(B-A) + (C-A), one ends to the point D.
You can retreive the position of the 3 other points using the normal of the rectangle. In order to orient a rectangle in space, you need 2 information:
its position, commonly represented as a 3 or 4 components vector, or a 4x4 matrix ;
its orientation, commonly represented as a quaternion.
If you have the orientation represented with a normal, and only have one point, you just can’t deduce the other points (because you need another information to solve the rotation equation around the normal). I think the best idea is to use quaternion to orient things in space (you can still retreive the normal from it), but you can also use a normal + one vector from the rectangle. You said you only have one point, and a tuple (width,height), so the common method based on the × operation won’t make it through.
I suggest you to:
make your Node class a class that correctly handles orientation; lookAt isn’t designed for that job ;
combine the translation matrix (position) with a cast matrix from the quaternion (orientation) to correctly handle both position and orientation ;
use that matrix to extract a rotated vector you’ll used like rotated × normal to get the 3 points.
Lets say i have a point with its position on 2d plane.
This point is going to change it position randomly, but thats not the point, so lets assume that it has its own velocity and its moving on plane with restricted width and height;
So after a while of movement this point is going to reach plane boundary.
But its not allowed to leave plane.
So now i can check point position each frame to see is it reached bound or not.
if(point.x>bound.xMax)point.x=bound.xMax
if i want point to teleport itself to second side of plane i can simply :
point.x = point.x%bound.xMax;
but then i need to store point position in integers.
For 10 milion values on my corei7 1.6 both solutions
have similar timings. 41ms vs 47 on second,
so there is no sense in using modulo function in that case, its faster to just check value.
But, is there any kind of trick to make it faster?
Multiple threads for iterating array approach is not a solution.
Maybe i can scale my bound value to some wierd value and for example discard a part of binary interpretation of position value.
And if there is some trick to do it i think that somebody did it before me :)
Do you know any kind of solution that could help me?
If there is some way you can add information around the plane coordinates you could very well make a "border" around the plane which contains a value that is identified as "out of boundaries". For example if you have a 10x10 board, make it 12x12 and use the 2 extra rows and columns to insert that information.
Now you can do (pseudo-code):
IF point IN board IS "out of boundaries value" THEN
do your thing
END IF
Note that this method is only an optimization if your point has both x and y values (my assumption on your case).