In G-codes a clockwise arc can be specified by e.g.
G02 X2 Y0 R2
This code should give an arc between the current position and (2,0) with radius=2.
According to several sources (And Math) eg.
There will always be two circles/arcs that satisfies these conditions each with a clockwise arc.
Which one is chosen and is it implementation/manufacturer dependent?
According to CNCCookbook's G-code Tutorial, it depends on the controller. Some controller use the sign of the radius to choose, some never lets you make an arc of more than 90°.
Given the two choices shown, the controller chooses the path based on the sign of the radius. Negative forces the longer arc, positive the shorter. The negative sign forces the controller to seek a viable arc of more than 180 degrees.
Some controllers are touchier still and will not program an arc that crosses a quadrant line. Hence, the largest angle an arc can follow is 90 degrees, and that angle must not cross 0, 90, 180, or 270 degrees. For angles of 90 degrees that cross a quadrant line, they must be broken into two pieces, with the join between the pieces being right on the quadrant line.
Related
Given a non-self-intersecting polygon as a list of points (p1...pn), and a point (A) outside that polygon:
I want to calculate the total angular field of view covered by the polygon from the point, as well as the direction from the point towards the middle of that field of view (as either a vector or angle from horizontal).
Visually, I want the angle Θ and direction of the green vector:
Diagram
I tried finding the minimum and maximum angles from horizontal to each of the polygon points, but I don't know how to tell which is the start of the range and which is the end. Assuming the smaller angle is the start gives incorrect results from the left of a simple box.
I'm guessing the solution will have something to do with whether the polygon points are in clockwise or counterclockwise order.
Whether the polygon goes clockwise or counterclockwise doesn't matter. What matters is that the extent of any edge, as seen from the point, must be less than π radians. That will tell us whether the edge -- as seen from the point -- goes counterclockwise from A to B, or from B to A.
For example, suppose the bearings (in radians) from the point to the vertices are {0, 2π/5, 4π/5, 6π/5, 8π/5}. If the edges are represented by the (unordered) pairs (A,C), (A,E), (B,D), (B,E), (C,D). Then the edges run:
0->4π/5
2π/5->6π/5
4π/5->6π/5
8π/5->0
8π/5->2π/5
So the range of the polygon is [8π/5, 6π/5].
I am currently trying to write a shader in unity that draws a triangular pattern around countries in a risk-styled game if both countries are not owned by the same player (visual aid to see your borders).
Right now, I'm having an issue with making the shader set the countries properly.
It always sets country 0 to the left, and country 1 to the right - country 0 and 1 are set programically.
The line, a border, can be between 0 and 359 degrees.
How I find the countries 0 and 1 is I draw 3 points to the left and right of the midpoint of the line, one .01f, one .1f and one 1f away from the midpoints in each direction, then spin them around the midpoint to the appropriate location.
After that I do an even-odd check to see if the points are inside or outside of each country, and compare the weight results (closest gets 3 points, mid gets 2, furthest gets 1, just in case someone builds a really screwed up country that flanks the other country).
In my test map, a close to equally sliced octagon, the borders showed up correctly (after I reversed the positions of country 0 and 1 in the event the angle was over 90 and less then or equal 180). Worked without a flaw, but in other maps it doesn't work very well.
Everything but the country allocation works well, so I'm curious if anyone knows of a better way to figure out which point is to the left or a spun line, or a better conceptual way to handle this.
That above is basically when I'm doing, red being left right being blue, then I'm just checking 3 different spots then weighing in the lefts and rights found with even/odding it into the appropriate countries (one at +/- .01, the other at +/- .1 and the third 1, in case of even/odd rounding issues with closeness).
I then flip them if I find that country A is to the right, as it is on the left according to the angles I had draw. (my shader renders left first and right second, hence why I do this).
which way is left/right on a line?
From last edit is this not your case. Why not use dot product?
So if the line goes in -x direction the result is negative and if in the +x direction then the result is positive. if the result is zero that means the line goes up or down only or it is juts a point. If you need specific direction instead of left/right then use appropriate a vector instead of x axis.
dot(a,b)=a.x*b.x+a.y*b.y in 2D
dot(a,b)=a.x*b.x+a.y*b.y+a.z*b.z in 3D
Image is relevant for cases where a vector is in unit size in that case the result of dot is perpendicular projection of b into a just like on image
on which side is some point?
I think this is what you need.
As you can see if you handle line (P0,P1) and point P you want to classify as triangle then its polygon winding determines also the side of the line. So for implicit axis directions:
CW(clockwise) polygon winding means right side of the line
CCW(counter-clockwise) polygon winding means left side of the line
How to get winding? ... simply compute normal vector and get its Z coordinate. Its polarity (sign) determines winding (CW/CCW or the other way around depends on the coordinate system).
normal vector is computed as cross product of the two vertices of triangle (P1-P0)x(P-P1)
No need to compute other axises just the z so:
normal.z = ((P1.x-P0.x)*(P.y-P1.y)) - ((P1.y-P0.y)*(P.x-P1.x))
Now just do if (normal.z<0) ... else ... it should never be zero unless you call it for point on the line or the line is a point ... look here at similar question: Determine rotation direction /toward/ variable point on a circle
I've got a tricky question today which involves a lot of vectors. I'm trying to keep them all straight. What I have is this shape (mostly hexagons with 12 pentagons): http://i.imgur.com/WDSWEcF.jpg
And I want to place 12 pentagon meshes into their 12 spots. I start by creating the 12 meshes at the origin (the center of this shape) and then using the following code to rotate and move them into position.
for (int i = 0; i < 12; ++i) {
Vector3 pentPoint = pentPoints.get(i); // The center of each pentagon.
ModelInstance pent = pents.get(i);
Vector3 direction = (pentPoint).cpy().sub(new Vector3(0, 0, 0))
.nor();
direction.set(direction.x, direction.y, direction.z);
pent.transform.setToRotation(Vector3.Y, direction);
pent.transform.setTranslation(pentPoint);}
Now, this is almost what I need. It results in this: http://i.imgur.com/Ch5Jhb8.jpg. Forgetting about the scaling for now, you can see that the pentagon is rotated improperly. It doesn't line up with its slot. I know that I can fix this rotation using pent.transform.rotate(Vector3.Y, *value*); based on some value for each pentagon. The problem is, I have no idea how I can calculate what this value should be.
Can anyone help or point me to some resources? Alternatively, I could use the fact that I know the coordinate of every vertex in the shape to fill in these pentagons by drawing triangles using LibGDX's ModelBuilder. I think this would be less performant than positioning the .objs. Thoughts?
I don't know anything about the library you're using, but maybe I can help with the geometry. One approach would be to draw a mesh for 1/5 of one of the pentagons. I suggest you do that in place, rather than at the origin. You need to know two adjacent vertices of a pentagon. From that, you can easily calculate the center of the pentagon (I can supply formulas if you wish). The three points you now have determine a triangle which is a "fundamental domain" for the rotation group of the dodecahedron. If you have a mesh on the fundamental domain, it can be propagated to the other 4/5 of the pentagon you chose by repeating a 72 degree rotation about the axis through the origin determined by the center of the pentagon. Call that rotation A. You can represent it by axis angle, quaternion, whatever.
To propagate the mesh to other pentagons in the figure, you just need one more rotation: a 180 degree rotation which takes your chosen pentagon to another nearby pentagon. Again, I could give a formula for the axis if you like, but if you can find the center of a second pentagon with the information you already have, the axis is determined by the midpoint of the segment connecting the two centers. (You may have to normalize the point determining the axis, depending on how you represent rotations.) Call the 180 degree rotation about that axis rotation B.
Rotation A and B together generate the entire 60 element rotation group of the icosahedron, which will allow you to propagate the mesh on the fundamental domain to every other pentagon in the figure. If you're not careful, however, you may hit some parts twice and others not at all. I think you can do it in this order: start with a fundamental domain. 4 A's fill in the first pentagonal face (let's call it the north pole). Then a B will map that pentagon to an adjacent pentagon. 4 more A's will fill in a meridian of pentagons. Another B will take a pentagon on the meridian to the other meridian. 4 more A's will fill in the second meridian. Finally another B will map a pentagon on the second meridian to the south pole.
The orientations of all the pentagons will be correct in this procedure.
Does that help?
I'm trying to find a way to calculate the intersection between two arcs.
I need to use this to determine how much of an Arc is visually on the right half of a circle, and how much on the left.
I though about creating an arc of the right half, and intersect that with the actual arc.
But it takes me wayyy to much time to solve this, so I thought about asking here - someone must have done it before.
Edit:
I'm sorry the previous illustration was provided when my head was too heavy after crunching angles. I'll try to explain again:
In this link you can see that I cut the arc in the middle to two halves, the right part of the Arc contains 135 degrees, and the left part has 90.
This Arc starts at -180 and ends at 45. (or starts at 180 and ends at 405 if normalized).
I have managed to create this code in order to calculate the amount of arc degrees contained in the right part, and in the left part:
f1 = (angle2>270.0f?270.0f:angle2) - (angle1<90.0f?90.0f:angle1);
if (f1 < 0.0f) f1 = 0.0f;
f2 = (angle2>640.0f?640.0f:angle2) - (angle1<450.0f?450.0f:angle1);
if (f2 < 0.0f) f2 = 0.0f;
f3 = (angle2>90.0f?90.0f:angle2) - angle1;
if (f3<0.0f) f3=0.0f;
f4 = (angle2>450.0f?450.0f:angle2) - (angle1<270.0f?270.0f:angle1);
if (f4<0.0f) f4=0.0f;
It works great after normalizing the angles to be non-negative, but starting below 360 of course.
Then f1 + f2 gives me the sum of the left half, and f3 + f4 gives me the sum of the right half.
It also does not consider a case when the arc is defined as more than 360, which may be an "error" case.
BUT, this seems like more of a "workaround", and not a correct mathematical solution.
I'm looking for a more elegant solution, which should be based on "intersection" between two arc (because math has no "sides", its not visual";
Thanks!!
I think this works, but I haven't tested it thoroughly. You have 2 arcs and each arc has a start angle and a stop angle. I'll work this in degrees measured clockwise from north, as you have done, but it will be just as easy to work in radians measured anti-clockwise from east as the mathematicians do.
First 'normalise' your arcs, that is, reduce all the angles in them to lie in [0,360), so take out multiples of 360deg and make all the angles +ve. Make sure that the stop angle of each arc lies to clockwise of the start angle.
Next, choose the start angle of one of your arcs, it doesn't matter which. Sort all the angles you have (4 of them) into numerical order. If any of the angles are numerically smaller than the start angle you have chosen, add 360deg to them.
Re-sort the angles into increasing numerical order. Your chosen start angle will be the first element in the new list. From the start angle you already chose, what is the next angle in the list ?
1) If it is the stop angle of the same arc then either there is no overlap or this arc is entirely contained within the other arc. Make a note and find the next angle. If the next angle is the start angle of the other arc there is no overlap and you can stop; if it is the stop angle of the other arc then the overlap contains the whole of the first arc. Stop
2) If it is the start angle of the other arc, then the overlap begins at that angle. Make a note of this angle. The next angle your sweep encounters has to be a stop angle and the overlap ends there. Stop.
3) If it is the stop angle of the other arc then the overlap comprises the angle between the start angle of the first arc and this angle. Stop.
This isn't particularly elegant and relies on ifs rather more than I generally like but it should work and be relatively easy to translate into your favourite programming language.
And look, no trigonometry at all !
EDIT
Here's a more 'mathematical' approach since you seem to feel the need.
For an angle theta in (-pi,pi] the hyperbolic sine function (often called sinh) maps the angle to an interval on the real line in the interval (approximately) (-11.5,11.5]. Unlike arcsin and arccos the inverse of this function is also single-valued on the same interval. Follow these steps:
1) If an arc includes 0 break it into 2 arcs, (start,0) and (0,stop). You now have 2, 3 or 4 intervals on the real line.
2) Compute the intersection of those intervals and transform back from linear measurement into angular measurement. You now have the intersection of the two arcs.
This test can be resumed with a one-line test. Even if a good answer is already posted, let me present mine.
Let assume that the first arc is A:(a0,a1) and the second arc is B:(b0,b1). I assume that the angle values are unique, i.e. in the range [0°,360°[, [0,2*pi[ or ]-pi,pi] (the range itself is not important, we will see why). I will take the range ]-pi,pi] as the range of all angles.
To explain in details the approach, I first design a test for interval intersection in R. Thus, we have here a1>=a0 and b1>=b0. Following the same notations for real intervals, I compute the following quantity:
S = (b0-a1)*(b1-a0)
If S>0, the two segments are not overlapping, else their intersection is not empty. It is indeed easy to see why this formula works. If S>0, we have two cases:
b0>a1 implies that b1>a0, so there is no intersection: a0=<a1<b0=<b1.
b1<a0 implies that b0<b1, so there is no intersection: b0=<b1<a0=<a1.
So we have a single mathematical expression which performs well in R.
Now I expand it over the circular domain ]-pi,pi]. The hypotheses a0<a1 and b0<b1 are not true anymore: for example, an arc can go from pi/2 to -pi/2, it is the left hemicircle.
So I compute the following quantity:
S = (b0-a1)*(b1-a0)*H(a1-a0)*H(b1-b0)
where H is the step function defined by H(x)=-1 if x<0 else H(x)=1
Again, if S>0, there is no intersection between the arcs A and B. There are 16 cases to explore, and I will not do this here ... but it is easy to make them on a sheet :).
Remark: The value of S is not important, just the signs of the terms. The beauty of this formula is that it is independant from the range you have taken. Also, you can rewrite it as a logical test:
T := (b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0)
where ^ is logical XOR
EDIT
Alas, there is an obvious failure case in this formula ... So I correct it here. I realize that htere is a case where the intersection of the two arcs can be two arcs, for example when -pi<a0<b1<b0<a1<pi.
The solution to correct this is to introduce a second test: if the sum of the angles is above 2*pi, the arcs intersect for sure.
So the formula turns out to be:
T := (a1+b1-a0-b0+2*pi*((b1<b0)+(a1<a0))<2*pi) | ((b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0))
Ok, it is way less elegant than the previous one, but it is now correct.
If I have calculated an intersection point between a line segment and a circle, how can I tell whether or not this intersection point lies on a segment of the circle?
I have the equations to tell whether or not a line segment intersects with the circle, and I also have the intersection point on that circle, but what I need to know is whether or not this collision point on the circle lies within the bounds of a specific arg segment of that circle. I have the end points of the arc segment, the circle's center & radius, and the point of collision.
Transform the intersection point into polar coordinates around the center and compare the angles.
As an alternative to Dario's idea (which should work as well), you can:
Calculate the distances between the intersection point and the endpoints of the arc (referred to as intdist1 and intdist2).
Calculate the distance between the endpoints of the arc (arcdist).
If the arc is less than half of the circle (covers less than 180 degrees), then you know if the point is in the arc if intdist1 and intdist2 are both less than arcdist.
Else, if the arc is greater than half the circle (covers more than 180 degrees), then you know if the point is in the arc if either intdist1 or intdist2 are greater than arcdist.
I'm guessing, since you haven't specified otherwise, that the arc between the endpoints goes the short way around. In that case, you don't need to worry about step 4 above.
The method fails though if you are using an arc that covers exactly 180 degrees of the circle. In that case you could break the 180 degrees arc into 90 degree arcs and check both of them I suppose.
Also, you can of course use the square of the distance for comparison of these distances to save yourself the square root. In addition, this method should be faster than calculating the angles because those involve using expensive inverse cosines.