Bezier curve in f(x) form - function

I'm trying to get a cubic bezier curve (four points) implementation in f(x) form. Obviously bezier curves aren't perfect functions, but if the last two points are within a square made between the first and second point then they are. I'm really not that great with maths - I barely understand the implementation of a normal bezier curve, and I have no idea how or if you can equate things together to get such a function. i.e. y = f(x).
That being said, I don't necessarily need a bezier curve, I just need a curve that goes from one point to another where I can define the gradients at both points. I've tried to mess around with mathematics to get such a function, and I managed to get a function which drives at the appropriate gradients, but not the appropriate height.
y = m1*x^2 / 2w + w(m1 - m2*x/2)
This function has (0,0) with gradient = m1
and (w, y) gradient = m2
The problem is that I can't figure out how to get the height between the two points into the equation. I had a method for another equation, where the new function was f(x) * h / f(w), but in this case that changes the gradients of the points in question.

Bezier spline is a parametric function of t and control points (four in case of cubic Bezier spline)
P(t) = f(t, P1, P2, P3, P4)
More precisely for 2D case:
x(t) = (1 - t)^3*x1 + 3*(1 - t)^2*t*x2 + 3*(1 - t)*t^2*x3 + t^3*x4
y(t) = (1 - t)^3*y1 + 3*(1 - t)^2*t*y2 + 3*(1 - t)*t^2*y3 + t^3*y4
where t in [0, 1].
It will be hard to express y(t) through x(t) as it's multiple-valued function in general case.

Related

Rotation order for eulers getPitch(), getRoll(), getYaw() from Quaternion in libgdx?

When transforming a quaternion to Euler Angles, usually there has to be a order in which the axes are rotated, like in this visualization.
How does it work for libgdx?
The Quaternion class has the functions
getRoll():
Math.asin(MathUtils.clamp(2f * (w*x - z * y), -1f, 1f)) :
(float)pole * MathUtils.PI * 0.5f;`
getPitch():
Math.asin(MathUtils.clamp(2f * (w*x - z * y), -1f, 1f)) :
(float)pole * MathUtils.PI * 0.5f;`
getYaw():
`
MathUtils.atan2(2f * (y * w + x * z), 1f - 2f * (y * y + x * x)) : 0f;`
Where is the order of the resulting angles set, which axes is rotated first,second,third ?
How are these functions related to a quaternion rotation matrix like:
Why is it that often this Rotationmatrix is given as Inverse /Transposed (equal because of orthogonality) ?
Rotation order
There are 12 possible orders of rotations possible for using an angle triplet for orientation.
Six of them are called Proper Euler angles, and rest six are called Tait–Bryan angles.
Read more here
Libgdx uses the following order.
Rotate by yaw about Y
Elevate by pitch towards Y
Rotate by roll about obtained direction
Rotation Matrix
Rotation matrices, Quaternions, Euler angles and Axis-Angle representation are different ways to encode rotation/orientation.
They often trade off between storage space and computation cost.
They can be freely converted into each other by means of well defined equations, one of which you mentioned. So these conversion expressions are related to each other.
Edit
Thanks for pointing out the mistake. It is indeed about Y axis not Z.
I have verified it from the source code.
Libgdx uses coordinate system of bullet physics engine. In that system, XZ plane is considered horizontal and Y is considered upwards (not Z). This was the root of my mistake.

Loss function for Bounding Box Regression using CNN

I am trying to understand Loss functions for Bounding Box Regression in CNNs. Currently I use Lasagne and Theano, which makes writing loss expressions very easy. Many sources propose different methods and I am asking myself which one is usually used in practice.
The bounding boxes coordinates are represented as normalized coordinates in the order [left, top, right, bottom] (using T.matrix('targets', dtype=theano.config.floatX)).
I have tried the following functions so far; however all of them have their drawbacks.
Intersection over Union
I was adviced to use the Intersection over Union measure to identify how well the 2 bounding boxes align and overlap. However, a problem occurs when the boxes don't overlap and then intersection is 0; then the whole quotient turns 0 regardless of how far the bounding boxes are apart. I implemented it as:
def get_area(A):
return (A[:,2] - A[:,0]) * (A[:,1] - A[:,3])
def get_intersection(A, B):
return (T.minimum(A[:,2], B[:,2]) - T.maximum(A[:,0], B[:,0])) \
* (T.minimum(A[:,1], B[:,1]) - T.maximum(A[:,3], B[:,3]))
def bbox_overlap_loss(A, B):
"""Computes the bounding box overlap using the
Intersection over union"""
intersection = get_intersection(A, B)
union = get_area(A) + get_area(B) - intersection
# Turn into loss
l = 1.0 - intersection / union
return l.mean()
Squared Diameter Difference
To create an error measure for non overlapping bounding boxes, I tried to compute the squared difference of the bounding box diameter. It seems to work, but I almost sure that there is much better way to do this. I implemented it as:
def squared_diameter_loss(A, B):
# Represent the squared distance from the real diameter
# in normalized pixel coordinates
l = (abs(A[:,0:2]-B[:,0:2]) + abs(A[:,2:4]-B[:,2:4]))**2
return l.mean()
Euclidean Loss
The simplest function would be the Euclidean Loss which computes the square root of the difference of the bounding box parameters squared. However, this doesn't take into account the area of the overlapping bounding box but only the difference of the parameters left, right, top, bottom. I implemented it as:
def euclidean_loss(A, B):
l = lasagne.objectives.squared_error(A, B)
return l.mean()
Could someone guide me on which would be the best loss function for bounding box regression for this use case or spot if I am doing something wrong here. Which loss function is usually used in practice?
Speaking from personal implementation experience, I had much better results training a CNN using IOU as the loss function as opposed to Euclidean (MSE or L2) Loss. Have not used the squared diameter difference loss. In general, a loss function that explicitly represents the goodness of your outputs for the tasks you hope to accomplish is probably best.
With regards to the IOU having a value of zero, you can introduce some additional term in the formulation so that it gracefully trends towards 0, perhaps based on normalized distance between bbox centers. This might give the additional effect of helping to center bounding boxes relative to the ground truth.
This response is mostly conceptual but I'd be happy to supply code examples if desired.

HTML5 Canvas - Wireframe Sphere in 2d

I'm looking to draw a 3D wire frame sphere in 2D Canvas. I'm not a math ninja by any means, so I'm wondering if anyone knows a simple way to draw one in Canvas using lineto arc connections and drawing it with :math:
I would appreciate any assistance.
Something like this: http://en.wikipedia.org/wiki/File:Sphere_wireframe_10deg_6r.svg
I'm hoping this is a simple equation, but if you know that it isn't (i.e. drawing that would be a lot of code), I would appreciate knowing that as well as I may need to reconsider what I wanna do.
The easiest for you would probably to view the source of the SVG file (here) and recreate those paths using canvas commands.
If you want an actual 3d sphere, projected onto 2d space, I'd suggest using a library like Three.js
You can also look at some of the math I've done here: swarms
The _3d and Matrix modules should be all that you need.
This time SO didn't help me, so I've helped myself and here it is: a pure HTML5 + JavaScript configurable rendering or a wireframe sphere.
I started from this excellent post and then went on. Basically I collected some vertex generation code from Qt3D and adapted to JS.
I'm not 100% sure the rotation functions are correct, but you are welcome to contribute back in case you find errors.
To be clearer, I've distinguished Z positions and draw white on the front and gray on the back.
Here's the result (16 rings x 32 slices) and related jsFiddle link
Enjoy
This is an old thread, but I had the same question and could not find any existing satisfying answer. That is, an answer other than "use WebGL" or "use Three.js". Lo and behold, I am the bearer of great news: it is actually possible to render such a sphere using exclusively Canvas2D's ellipse function, giving us:
a straightforward implementation (~130 lines everything included)
no need for computing vertices and edges
sexy smooth edges
You can find a demo on JSBin, for posterity, with a bunch of options.
The key is to notice that the "wireframe" we're trying to draw is solely composed of circles, and every circle rotated in 3d space will get projected to the camera as an ellipse. The question, then, is: how to find the ellipse corresponding to the projection of the rotated circle?
As we are only interested in circles that lay on the surface of the sphere, we can characterize each of them by the (inter)section of a plane and the (unit) sphere. Therefore, each circle can be described by a normal vector and an offset -1 < o < 1.
Then it's not too difficult to compute and draw the ellipse resulting from the projection of the circle:
function draw_section(n, o = 0) {
let {x, y, z} = project(_p, n) // project normal on camera
let a = atan2(y, x) // angle of projected normal -> angle of ellipse
let ry = sqrt(1 - o * o) // radius of section -> y-radius of ellipse
let rx = ry * abs(z) // x-radius of ellipse
let W = sqrt(x * x + y * y)
let sa = acos(clamp(-1, 1, o * (1 / W - W) / rx || 0)) // ellipse start angle
let sb = z > 0 ? 2 * PI - sa : - sa // ellipse end angle
ctx.beginPath()
ctx.ellipse(x * o * RADIUS, y * o * RADIUS, rx * RADIUS, ry * RADIUS, a, sa, sb, z <= 0)
ctx.stroke()
}
The disks from your example image can be obtained by:
rotating a plane around the z axis
shifting a plane along the z axis
function draw_arcs() {
for (let i = 10; i--;) {
let a = i / 10 * Math.PI
draw_section(vec.set(_n, cos(a), sin(a), 0))
}
for (let i = 9; i--;) {
let a = (i + 1) / 10 * Math.PI
draw_section(Z, cos(a))
}
}
A nice benefit of this method is that you can do this "shifting a plane along the Z axis" for all axes, resulting in a lovely wireframe that would be hard to reproduce if computing vertices and edges by hand:
The only change was the following:
function draw_arcs() {
for (let i = 9; i--;) {
let a = (i + 1) / 10 * Math.PI
draw_section(Z, cos(a))
draw_section(X, cos(a))
draw_section(Y, cos(a))
}
}
The function draw_section above was carefully crafted so that it only draws the camera-facing arc of a given section, which means we get occlusion-culling for free.
(and my dirty trick to render the back of the sphere with a different color is to run draw_arcs again after flipping the canvas)
It's also possible to use 2 radial gradients to have some fake depth shading like in your image:
Sadly browsers seem to struggle a lot when drawing paths with gradients.
There are but two drawbacks I see right now:
performance may vary between browsers. It's likely some optimization could be done, like merging successive calls to .stroke() into one. Frankly quite surprised by how slow using ellipse seems to be at times.
it's a parallel projection rather than a perspective one. If we were to add perspective, projected circles would still appear as ellipses, but the calculation of the ellipse would be a tad more involved. I haven't done it yet, I expect it to be possible, might update my answer if I succeed.
Look at this one: http://jsfiddle.net/aJMBp/
you should just draw a lot of these lines to create a complete sphere. This is a good starting point, give me 5 minutes and I'll see if I can improve it to draw a sphere.
Getting better:
http://jsfiddle.net/aJMBp/1/
Ok, thats def out of my capacity. However, another little improvement here: http://jsfiddle.net/aJMBp/2/

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.