Halcon - Generate new pose based on 2 poses - intersection

I have 2 Parallel poses with different origins and different X axis directions (Y is parallel):
First pose is my ground plane. X is horizontal, Y is vertical, Z is depth.
Second pose, is somewhere above the first pose floating in the room, with the Y Axis parallel to the first pose's Y axis.. X and Z can be rotated along the Y axis...
What I need, is a third pose that is The second pose, but lowered onto the first pose, so that Y0 of the third pose is the same as the Y0 of the first pose.
I am going crazy about this, cant figure out how to do it.
any help appreciated...
EDIT: I have updated the question to simplify the problem a little bit.

Related

Explain what is happening with RotateTo with different X and Y?

RotateTo comes with two create methods - one which lets you specify only a single angle to rotate to, and another where one can specify a different angle for X and Y.
I don't understand what is going on when you use the latter (specifying angles for both X and Y). In the form, its just that the same angle is used for both.
Can someone explain what is actually going on when you specify two different angles, and the situation when this would actually be useful ? I've tried it out, but I can't figure out how this is useful ?
EDIT: I'm aware that the output using different x,y vs same looks different. I've actually tried it out myself. My question is - what's the point ? In which situation is it useful?
There are difference's between giving single angle and two different x and y. For Single we are giving an angle for example 90° , In case of the second We will give separate angle for both x and y to create an action. The look of animation differs from both. Usage of them actually depends on your project needs.
For Eg If you code like below
Single Angle :- CCFiniteTimeAction* actionRotate1 = CCRotateTo::create(6.0, 90);
or
Different x and y Angle :- CCFiniteTimeAction* actionRotate1 = CCRotateTo::create(6.0, 90,90);
The output will be like this
90° Output
But when you give different angle the difference between the animations can be felt for giving single angle and giving different angle's for x and y.
Single Angle :- CCFiniteTimeAction* actionRotate1 = CCRotateTo::create(6.0, 540);
The output is :- Single Angle Output
Different x and y Angle :- CCFiniteTimeAction* actionRotate1 = CCRotateTo::create(6.0,0,540);
The output is :- Different x and y Output
You can feel the animation changes when we give different angles for both x and y. It gives you flip like animation look but in case of single angle, the specified images is just rotated to the desired angle.
Hope this helps you.

Distance between points on surface of cube

Let (x1, y1, z1) and (x2, y2, z2) be two points in Euclidian 3-space on the surface of an axis-aligned side-length-2 cube centered at the origin.
How do I efficiently compute the distance (or squared distance) between the points over the surface of the cube?
Internally, I represent points as (offset1, offset2, faceNumber) but an (x,y,z) format (as referenced above) is readily available.
I prefer C or Python code but I'll happily accept pseudocode or anything, really.
EDIT:
Some facts:
Shortest paths are always monotone in x, y, and z.
If the points are on the same face then it's trivially just Euclidian distance.
If the points are not on the same face, the shortest path could involve either 2 or 3 faces.
EDIT: What I would do, is turn the 3d cube into a 2d plane. The caveat is that, if the point is on the opposite side of the cube, you need to place the final surface on all ends of the cross.
If a cube had sides like this that you could fold around so that 4 touched side 1.
5
1 2 3 4
6
You would have a 2d plane that ultimately looked like this
3
4/5 5 5/2
3 4 1 2 3
4/6 6 2/6
3
So, I modified this. Now each of the corner panels represents the connections that can take place between both panels. When you initially lay out this array, each point on panels 2, 4, 5, and 6, will map to three points. The solution is then the shortest line to any of the given points, that represent point 2, in the event you need to map it to multiple points.
Mapping points from the 3d cube, to their initial 1 - 6 pains on the 2d graph is really quite simple. The only difficulty left is figuring out how to map points from the 2 plane, onto the "2/6" plane and so forth. This is just a matter of thinking through each situation. Ex: 2 -> 2/6 is different from 5 -> 5/2. My intuition is that it's either going to be 90 degree or -90 degree rotation, before shifting the width of the cube in the appropriate direction.
For example, to properly handle the situation you laid out we would have a value at the bottom left corner of plane one, and the bottom right corner of plane 2. After the following: '
points in plane 2/6 = rot90(points in plane 2) - width of the cube.
We will have a point in the bottom left corner of plane 2/6. This will then appropriately be the shortest path, and appropriately this path crosses the face of plane 6.

Blending two functions, where one is inverse

Let me first explain the idea. The actual math question is below the screenshots.
For musical purpose I am building a groove algorithm where event positions are translated by a mathematical function F(X). The positions are normalized inside the groove range, so I am basically dealing with values between zero and one (which makes shaping groove curves way easier-the only limitation is x'>=0).
This groove algorithm accepts any event position and also work by filtering static notes from a data-structure like a timeline note-track. For filtering events in a certain range (audio block-size) I need the inverse groove-function to locate the notes in the track and transform them into the groove space. So far so good. It works!
In short: I use an inverse function for the fact that it is mirrored to (y=x). So I can plug in a value x and get a y. This y can obviously plugged into the inverse function to get first x again.
Problem: I now want to be able to blend the groove into another, but the usual linear (hint hint) blending code does not behave like I expected it. To make it easier, I first tried to blend to y=x.
B(x)=alpha*F(x) + (1-alpha)*x;
iB(x)=alpha*iF(x) + (1-alpha)*x;
For alpha=1 we get the full curve. For alpha=0 we get the straight line. But for alpha between 0 and 1 B(x) and iB(x) are not mirrored anymore (close, but not enough), F(x) and iF(x) are still mirrored.
Is there a solution for that (besides quantizing the curve into line segments)? Any subject I should throw an eye on?
you are combining two functions, f(x) and g(x), so that y = a f(x) + (1-a) g(x). and given some y, a, f and g, you want to find x. at least, that is what i understand.
i don't see how to do this generally (although i haven't tried very hard - i mean, it would be worth asking someone else), but i suspect that for "nice" shaped functions, like you seem to be using, newton's method would be fairly quick.
you want to find x such that y = a f(x) + (1-a) g(x). in other words, when 0 = a f(x) + (1-a) g(x) - y.
so let's define r(x) = a f(x) + (1-a) g(x) - y and find the "zero" of that. start with a guess in the middle, x_0 = 0.5. calculate x_1 = x_0 - r(x_0) / r'(x_0). repeat. if you are lucky this will rapidly converge (if not, you might consider defining the functions relative to y=x, which you already seem to be doing, and trying it again).
see wikipedia
This problem can't be solved algebraically, in general.
Consider for instance
y = 2e^x (inverse x = log 0.5y)
and
y = 2x (inverse x = 0.5y).
Blending these together with weight 0.5 gives y = e^x+x, and it is well-known that it is not possible to solve for x here using only elementary functions, even though the inverse of each piece was easy to find.
You will want to use a numerical method to approximate the inverse, as discussed by andrew above.

How can I better pack rectangles tangent to a sphere for a 3d gallery?

I am creating a 3D sphere gallery with ActionScript 3 and the Flash 10 3D (2.5D) APIs. I have found a method that works but is not ideal. I would like to see if there is a better method.
My algorithm goes like this:
Let n = the number of images
h = the height of each image
w = the width of each image
Approximate the radius of the circle by assuming (incorrectly) that the surface area of the images is equal to the surface area of the sphere we want to create.To calculate the radius solve for r in nwh = 4πr2. This is the part that needs to be improved.
Calculate the angle between rows. rowAngle = 2atan(h / 2 / r).
Calculate the number of rows.rows = floor(π / rowAngle).
Because step one is an approximation, the number of rows will not fit perfectly, so for presentation add padding rowAngle.rowAngle += (π - rowAngle * rows) / rows.
For each i in rows:
Calculate the radius of the circle of latitude for the row.latitudeRadius = radius * cos(π / 2 - rowAngle * i.
Calculate the angle between columns.columnAngle = atan(w / 2 / latitudeRadius) * 2.
Calculate the number of colums.columns = floor(2 * π / columnAngle)
Because step one is an approximation, the number of columns will not fit perfectly, so for presentation add padding to columnAngle.columnAngle += (2 * π - columnAngle * column) / column.
For each j in columns, translate -radius along the Z axis, rotate π / 2 + rowAngle * i around the X axis, and rotate columnAngle * j around the Y axis.
To see this in action, click here. alternate link. Notice that with the default settings, the number of items actually in the sphere are less by 13. I believe is the error introduced by my approximation in the first step.
I am not able to figure out a method for determining what the exact radius of such a sphere should be. I'm hoping to learn either a better method, the correct method, or that what I am trying to do is hard or very hard (in which case I will be happy with what I have).
I would divide this problem into two connected problems.
Given a radius, how do you pack things on to the sphere?
Given a number of things, how do you find the right radius?
If you have a solution to the first problem, the second is easy to solve. Here it is in pseudo-code.
lowerRadius = somethingTooSmall
fittedItems = itemsForRadius(lowerRadius)
while fittedItems < wantedItems:
lowerRadius *= 2
fittedItems = itemsForRadius(lowerRadius)
upperRadius = 2 * lowerRadius
while threshold < upperRadius - lowerRadius:
middleRadius = (upperRadius + lowerRadius)/2
if itemsForRadius(middleRadius) < wantedItems:
lowerRadius = middleRadius
else:
upperRadius = middleRadius
This will find the smallest radius that will pack the desired number of things with your packing algorithm. If you wish you could start with a better starting point - your current estimate is pretty close. But I don't think that an analytic formula will do it.
Now let's turn to the first problem. You have a very reasonable approach. It does have one serious bug though. The bug is that your columnAngle should not be calculated for the middle of your row. What you need to do is figure out the latitude which your items are in that is closest to the pole, and use that for the calculation. This is why when you try to fit 10 items you find a packing that causes the corners to overlap.
If you want a denser packing, you can try squishing rows towards the equator. This will result in sometimes having room for more items in a row so you'll get more things in a smaller sphere. But visually it may not look as nice. Play with it, and decide whether you like the result.
BTW I like the idea. It looks nice.
In the case of squares, it seems to be an approximate formula for knowing the relationship between the radius, the square's side and the number of squares embedded.
Following this, the number of squares is:
Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -a/2, a/2}]]
or
Floor[(Pi r)/ArcCot[(2 Sqrt[2] r Sqrt[a^2+2 r^2])/a^2]]
where
r = Radius
a = Square side
If you plot for r=1, as a function of a:
Where you can see the case a=2 is the boundary for n=6, meaning a cube:
Still working to see if it can be extended to the case of a generic rectangle.
Edit
For rectangles, the corresponding formula is:
Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -b/2, b/2}]]
which gives:
Floor[(2 Pi r)/(Pi-2 ArcTan[(2 r Sqrt[a^2+b^2+4 r^2])/(a b)])]
where
r = Radius
a,b = Rectangle sides
Let's suppose we want rectangles with one side half of the other (b = a/2) and a sphere of radius 1.
So, the number of rectangles as a function of a gives:
Where you may see that a rectangle with a "large" side of size 2 allows 10 rectangles in the sphere, while a rectangle of "large" side 4 allows only 4 rectangles.

Rotate a circle around another circle

Short question: Given a point P and a line segment L, how do I find the point (or points) on L that are exactly X distance from P, if it guaranteed that there is such a point?
The longer way to ask this question is with an image. Given two circles, one static and one dynamic, if you move the dynamic one towards the static one in a straight line, it's pretty easy to determine the point of contact (see 1, the green dot).
Now, if you move the dynamic circle towards the static circle at an angle, determining the point of contact is much more difficult, (see 2, the purple dot). That part I already have done. What I want to do is, after determining the point of contact, decrease the angle and determine the new point of contact (see 3, 4, the red dot).
In #4, you can see the angle is decreased by less than half, and the new point of contact is half-way between the straight-line point and the original point. In #7, you can see the angle is bisected, but the new point of contact moves much farther than half way back towards the straight-line point.
In my case, I always want to decrease the angle to 5/6ths its original value, but the original angle and distance between the circles are variable. The circles are all the same radius. The actual data I need after decreasing the angle is the vector between the new center of the dynamic circle and the static circle, that is, the blue line in 3, 4, 6, and 7, if that makes the calculation any easier.
So far, I know I have to move the dynamic circle along the line that the purple circle is a center of, towards the center of the static circle. Then the circle has to move directly back towards the original position of the dynamic circle. The hard part is knowing exactly how far back it has to move so that it's just touching the other circle.
To answer your short question, if you are on the Cartesian plane, then find the equation of the line L is sitting on (given the two endpoints of L, this is simple). Find the equation of the perpendicular to said line, which passes through P (this is done by taking the negative inverse of the slope, plugging in P's x and y values, and solving for the intercept). Then find the point where the two perpendicular lines intersect by using their equations as a single system of equations (with x's and y's equal). Then find the distance between the point of intersection and the point P, which is one leg of a triangle. Finally, with that distance and the distance X you are given, use Pythagorean theorem to find the distance of the other leg of the triangle. Now the point you are looking for is a point on L, and also on the line on which L sits. So using the distance you just obtained, the intersection point you had found before, and the equation of L's line, you can find the desired point's coordinates. There can only be a maximum of 2 such points, so all you have to test for is whether the coordinates of the points found are actually on L, or beyond L but still on its line. Sorry for the long answer and if you wanted a geometric explanation rather than an algebraic one.
Draw a circle with the same centre as the stationary circle and the radius of the sum of both radii. There are two intersections with the translation line of the moving circle's centre. The place of the moving circle's center at the time of contact is the closer of those two intersections.
Let the ends of your segment be A and B, and the center of your stationary circle be C. Let the radius of both circles be r. Let the center of the moving circle at the moment of collision be D. We have a triangle ACD, of which we know: the distance AC, because it is constant, the angle DAC, because that's what you are changing, and the distance CD, which is exactly 2r. Theoretically, two sides and angle should let you get all the rest of a triangle...