I've started to use JSXGraph to draw a function. It should be a simple straight line (budget curve) that has a half-circle as his tangent (an indifference curve).
Furthermore the tangent should move with the line, if the line is moved.
Is this possible in JSXGraph?
Edit: The Curve and the function should look similar to this graph:
https://www.economicsonline.co.uk/Pictures2017/Grid-indifference-Basic-Equilibrium-new.png
Thanks,
Mike
Yes, it is possible with JSXGraph. One approach is to start with a point A and fix the slope s of the budget curve through A as well as the radius r of the circle line.
Doing the relatively straightforward math gives as coordinates of the center M of the circle:
M = A + r / sqrt(r*r + 1) * [-s, 1]
The equation of the circle line is
(y - M_y)^2 + (x - M_x)^2 = r^2
It follows that the indifference curve is
y = -sqrt(r^2 - (x - M_x)^2) + M_y
We take the negative square root, since we want to take the lower semicircle as indifference curve. A working example is at http://jsfiddle.net/4sg1dpq8/
Related
I am currently working on an app for which I need to convert VML shapes into SVG shapes. While I can handle all other aspects of it, I am facing problem in correctly converting the path of the shape from VML path to SVG path. I am using a combination of XSLT and Javascript for my codes.
I have enough control on conversion of angular shapes (i.e. shapes containing only straight lines) but I am facing difficulty in converting path with curves.
For instance, for a simple shape this:
The VML path is: m10800,qx21600,10800,10800,21600l,21600,,xe
Now if I replace m with M, l with L and qx with Q and do the necessary scaling of the coordinates I get the following SVG shape:
The SVG path treats first set of coordinates in Q/qx as a control point and hence the actual path doesn't passes through the point whereas the VML intended those coordinates as the point over which the path should pass through. I don't understand how I can achieve that with SVG (i.e. making sure that the path passes through a specific point or points).
Currently I am using this and this for researching SVG and VML respectively. I also tried using Vector Converter 1.2 but that doesn't works either.
Can anyone suggest me a way, a library, any study links or tutorials where I can find a solution to my problem?
Thanks in advance!!
"qx" in VML is an "elliptical quadrant", "Q" in SVG is a quadratic bezier. Completely different things.
The simplest solution to converting a "qx" is to approximating it with a cubic bezier. Using an arc would be most accurate, but there will be some tricky maths involved in order to determine the correct value for "sweep flag". Although a cubic bezier is not a perfect approximation to a quadrant, it is very close, and the error will not be noticeable enough to affect your drawings.
The secret to drawing circular/elliptical quadrants is the constant 0.5522847498. It defines how long the control point lines have to be to simulate the elliptical curve. You can find explanations for how it is derived by googling that number.
So VML defines "qx" as an elliptical quadrant starting out in the X direction. So given the path command "qx21600,10800", the algorithm for conversion will be:
arcFactor = 0.5522847498;
currentX = 10800;
currentY = 0; // start coords (from the move)
x = 21600;
y = 10800; // first coords in "qx"
dx = x - currentX;
dy = y - currentY;
// Calculate first control point
cp1x = currentX + dx * arcFactor;
cp1y = currentY; // starts out horizontal
// Calculate second control point
cp2x = x;
cp2y = y - dy * arcFactor;
svgBezier = "C" + cp1x + "," + cp1y + "," + cp2x + "," + cp2y + "," + x + "," + y;
Now your curve has a second set of coordinates to the qx. The spec says that it means a repeat of the "qx" command. However it makes no sense for the second set to behave exactly the same as the qx (ie. start out horizontal). So I think they must actually behave as a "qy" (start out vertical). Ie. the qx and qy alternate. Assuming that is the case, the calculation for the qy should be:
// Calculate first control point
cp1x = currentX; // starts out vertical
cp1y = currentY + dy * arcFactor;
// Calculate second control point
cp2x = x - dx * arcFactor;
cp2y = y;
Demo fiddle is here
I am creating a piechart with D3 using d3.layout.pie().
It looks like this one, without black dots (I've put them manually in Photoshop to illustrate my issue). I wonder how I can calculate coordinates of these dots, that are in the middle of the surface to place some tooltips there. I am not asking for a finished solution but more about the principle how to do it.
Thanks.
You can use the following equations to calculate a point along the circumference of a circle:
x = cx + r * cos(a)
y = cy + r * sin(a)
Where (cx, cy) is the center of the circle, r is the radius, and a is the angle.
In order for this to work for you, you will need a way to computing the angle based upon the pie slices on your chart - see below.
According to the d3 documentation for pie layouts, the pie function returns a list of arcs, so you can process this data to calculate each of your points:
pie(values[, index])
Evaluates the pie function on the specified array of values. An optional index may be specified, which is passed along to the start and end angle functions. The return value is an array of arc descriptors
value - the data value, returned by the value accessor.
startAngle - the start angle of the arc in radians.
endAngle - the end angle of the arc in radians.
data - the original datum for this arc.
Presumably you could just take half the distance between endAngle and startAngle for each arc, and place your point there.
For what it's worth, here is the code from pie.js that is used to compute each arc:
// Compute the arcs!
// They are stored in the original data's order.
var arcs = [];
index.forEach(function(i) {
var d;
arcs[i] = {
data: data[i],
value: d = values[i],
startAngle: a,
endAngle: a += d * k
};
});
return arcs;
Does that help?
I know its been a year you asked this questions but just dropping in an answer which might help others.
Try Using the arc.centriod() in the transform of the circles you want to display.
Something like this
enterMenu.append("circle")
.attr("r", 5)
.attr('transform',function(d){
return "translate(" + arc.centriod(d) + ")";
});
This should place the circle exactly in between the slice. In the above function d is the endAngle of the arc.
For you reference Check out this link http://bl.ocks.org/Guerino1/2295263
It may sound trivial but I was trying to find the x and y coordinates inside each slice, and when I saw the formula posted above,
x = cx + r * cos(a)
y = cy + r * sin(a)
, it can be done by increasing r from (cx+1 or cy+1) to radius length, and repeating by increasing (a) from origin angle to destination angle, then adding (cx, cy). Hope it helps someone.
I've been experimenting with HTML5 canvases lately and came across this 3d example with relatively little code behind it. I was hoping to find a good introduction to 3d rendering, but I'm having more trouble understanding the geometry behind the code than I was expecting to. I set up a JSbin and copied over the code that was used on his website to play with. I'm stuck at understanding the meaning of
deltaX=1/Math.cos(theta);
which is later used in:
if (deltaX>0) {
stepX = 1;
distX = (mapX + 1 - x) * deltaX;
}
else {
stepX = -1;
distX = (x - mapX) * (deltaX*=-1);
}
Source
My best guess is that it's used for the relation cos(x) = adjacent/hypotenuse in a right triangle, but I don't understand where the triangle would fit in, if at all.
If you draw a line from the origin (0, 0) with direction theta (measured from the x-axis), then
deltaX = 1/cos(theta) is the distance on this line until the vertical line x = 1 is met, and
deltaY = 1/sin(theta) is the distance on this line until the horizontal line y = 1 is met.
It is indeed a triangle relation. In the first case, the triangle has the points (0, 0), (1, 0) and the point (1, y) where the line meets the vertical line x=1.
(mapX, mapY) is a grid point with integer coordinates, and (x, y) is a point in the square [mapX, mapX+1) x [mapY, mapY+1).
distX computes the distance of the next vertical grid line in theta-direction, and distY the distance of the next horizontal grid line.
Remark: The computation fails if the direction is a multiple of π/2, i.e. the direction is exactly right, up, left, or down, because sin(theta) = 0 or cos(theta) = 0 in that case. This probably does not happen in your program, because the playerDirection starts with 0.4 and is incremented or decremented by 0.07.
I have a programming question with some math weight. I have a map with shapes(polylines) drown on it. I can take the screen coordinates of that shapes and translate them to map coordinates and reverse. I am capturing mouse position and moving around the map. How can I recognize if I come in proximity to another shape drown on the map while I am moving the mouse. I was thinking to create a radius of points around the mouse cursor, then constantly looping trough available shapes (I imagine I can load their coordinates in arrays) for a match. However that will be very slow I think. The point is that when I am in proximity (for example 15px) I will snap the muse position to that close shape. Any suggestions?
Now - if you really want to make it perfect - you can calculate the distance of a cursor to each line segment.
For each line segment (defined by points D and E)
Calculate line formula for segment DE in format:
Ax + By + C = 0
A = D.y - E.y
B = E.x - D.x
C = (plug in point D) = -1 * (A * D.x + B * D.y)
Now plug in your cursor position to the formula:
A * cursor.x + B * cursor.y + C = YOUR DISTANCE TO THE LINE SEGMENT
*One thing - this is distance to the unbounded line. You now want to make sure that you are between the two segment points. So make sure the angles in your cursor, D, E triangle are all < 90 degrees. A number of ways to do that, look into the dot product formula to learn a fast one.
Now if anlges are less than 90, use the distance to the line, else, use the min distance to either point of segment (D & E). Now you have a complete snap to lines functionality.
If you have every point / line segment of the shapes (which you should with the polylines), here is a possible quick and simple routine:
For each shape
Figure center of shape by averaging each constituent point (i.e. - for a pentagon, add all five point.x up, divide by 5 - do same for all point.y). Call this average shape.x and shape.y. Use distance formula to figure proximity to your mouse. (Mouse.x - Shape.x)^2 + (Mouse.y - Shape.y)^2... you don't have to take the square root of that since you are only interested in the closest shape.
Keep track of the minimum distance "squared" for each shape. The minimum is your closest shape center.
If you want snap to behavior with a maximum range, just also make sure the distance squared is < pixel distance squared.
If you want to make it very effiecient, the shape centers do not need to be constantly refigured, just calculated once. The center will scale and translate the same as any other point if you are converting between screen space and other coordinates as you mentioned.
I have a slice of a circle (that is made of moveTo,lineTo,arc,etc) and need to find the middle point of the slice.
What is the math behind finding the point shown in the image below?
It looks "centroid" of the sector to me.
The co-ordinates of it (with x axis along the radius passing through the centroid and origin at the centre)
centroidX = (4/3)r(sin(A)/A)
centroidY = 0
where 'A' is the angle made by the arc at the centre(in radians) and 'r' is the radius.
EDIT:
This is sort of a formula which can be easily derived.
Geometric Centroid of any shape is average(weighted mean) of all it's points.
In physics, centroid(AKA centre of mass) of an object is the point at which the mass of the whole object can be assumed to be concentrated(eg, the object can be balanced on a needle at the centroid). There are formulae which can be directly used for regular shapes. For irregular shapes, it is calculated by integration.
It's basic logic is adding x co-ordinates of all the points and dividing by total no. of points, which gives x co-ordinate of the centroid and similar for y co-ordinate.
As the points on a shape are not discrete, integration is used.
Let C is center point, P1 and P2 are points at circumference, and slice angle is smaller then Pi (180 deg).
One possibility:
X = C + Radius/2 * UnitVector(P1 + P2 - 2*C)
Another:
X = 1/3 * (P1 + P2 + C)
(It depends on exact requirements)