I have a task - draw smooth curve
input: set of points (they added in realtime)
current solution: I use each 4 points to draw qubic Bezier curve (1 - strart, 2 and 3rd - control points, 4- end). End point of each curve is start point for the next one.
problem: at the curves connection I often have "fracture" (angle)
Can you tell me, how to connect my points more smooth?
Thanks!
Here is few references which can help you:
Draw a Smooth Curve through a Set of 2D Points with Bezier Primitives
Curve fitting
Line Smoothing and point-weeding
Related
Let's say I have Quadratic Bezier Curve like the black one.
I want to create a prallel Bezier Curve like red one.
How can I do that?
My Approach:
Let's draw using quadraticBezierTo(controlePoint, endingPoint). Assume startingPoint=(0,0)
2.Using equation of quadratic bezier curve, let's find an array of points
Let's draw these new points offsetting them a few pixel horizontally in left side.
What could be the better way of doing it?
Most of the times, I determine contour orientation generating 2D points and computing the closed polygon area. Depending on the area value sign I can understand if the contour is oriented clockwise or not (see How to determine if a list of polygon points are in clockwise order?).
Would it be possible to do the same computations without generating 2D points? I mean, relying only on geometric curve properties?
We are interested in determining the orientation of contours like these ones without sampling them with 2D points.
EDIT: Some interesting solutions can be found here:
https://math.stackexchange.com/questions/423718/general-way-to-find-out-whether-a-curve-is-positively-oriented
Scientific paper: Determining the orientation of closed planar curves, DJ Filip (1990)
How are those geometric curves defined?
Do you have an angle for them? The radius doesn't matter, only the difference between entry-angle and exit-angle of each curve.
In that case, a trivial idea crossing my mind is to just sum up all the angles. If the result is positive, you know you had more curves towards the right meaning it's a clockwise contour. If it was negative, then more curves were leftwards -> anti-clockwise contour. (assuming that positive angels determine a right-curve and vica versa)
After thinking about this for awhile, for polygons that contain arcs I think there are three ways to do this.
One, is to break the arcs into line segments and then use the area formula as described above. The success of this approach seems to be tied to how close the interpolation of the arcs is as this could cause the polygon to intersect itself.
A quicker way than the above would be to do the interpolation of the arcs and then find a vertex in the corner (minimal Y, if tie minimal X) and use the sign of the cross product for that vertex. Positive CCW, negative CW. Again, this is still tied to the accuracy of the interpolation.
I think a better approach would be to find the midpoint of the arc and create two line segments, one from the beginning of the arc to the midpoint and another from the midpoint to the end of the arc and replace the arc with these line segments. Now you have a polygon with only line segments. Then you can add up all the normalized cross products of all the vertices. The sign will tell you the direction. Positive is counter-clockwise, negative is clockwise. In this case it doesn't matter if the polygon self-intersects.
I tried to create this very unique shape in swift a long time ago but failed. My goal is to draw a shape like in this image here (I mean the darker shape in that image).
How can you create such a unique shape in Swift?
As Alexander says, it looks like that shape would be pretty easy to create using Bezier curves.
I'd suggest opening that image in a program like Photoshop that offers a Bezier path drawing tool and trying to recreate it there. Once you have the control points that get you the shape you are after, you can write down their coordinates and recreate them using a UIBezierPath in iOS.
A cubic bezier path has 2 end points and 2 middle control points. The curve moves from the starting point to the ending point, and gets pulled towards the first middle control point first, and then pulled towards the second control point. You can create a wide variety of curves that have 2 "humps" in them with a single Bezier curve, and you can chain multiple Bezier curves together to create more complex shapes. If you arrange the control points for connecting Bezier curves correctly you can get curves that transition smoothly from one to the next. With a different arrangement of the control points between Bezier curves, you can create sharp corners between curves.
I suggest you google Bezier curves, and do some experimenting.
I'm not particularly good with the path tool in Photoshop, but I got pretty close with a few minutes tinkering. here is a screen-shot:
I am doing some work related to eye images.
I did edge detection to it. The edge is like a curve and not continuous. I have to assume it to be continuous and find normals to that curve. How do I find the normals to it using MATLAB?
you can see the image below.
I want to find the normals to the upper curve.
I hope that I was clear enough.
Even though it seems unintuitive, the edge direction at every pixel is a pretty good estimate of the normal. This would be the simplest solution, because it doesn't involve any curve fitting.
In MATLAB, you can find pixel-wise edge directions using the Sobel filter:
[BW,thresh,gv,gh] = edge(I,'sobel');
edgeDir = atan2(gv, gh);
This gives you the edge directions as angles in radians.
You may want to consider curve fitting (MSE based or some other criteria) to the data. I believe a second order will do good for the upper curve, and once you have a model you can can calculate the tangent and normal at each point.
As Zaphod recommended the normal is perpendicular to the edge. You don't need to do curve fitting, you can use back projection to identify the focal point of the curve.
Start at each edge point along the curve and draw a line from curve in the direction of the normal. Draw the line by incrementing the value of each pixel the line passes through. Once you do this for all the edges you would hope to find two pixels with higher values then the rest, one for each of your curves. You should then know by there locations which is the focal point for each curve.
so I have created a circle with draw method :
glLineWidth(16);
glColor4ub(0, 255, 0, 255);
drawCircle( ccp(s.width/2, s.height/2), 100, 0, 10, NO);
I would like to know if it is possible to transform this shape to a rectangle shape with animation . Thank you . sorry for my english I'm french :/
For simplicity, I'd use 4 cubic bezier curves - one curve per quadrant of the circle. (This isn't a perfect circle but neither is a 100 segment circle!) Then, using the schedule: functionality provided by cocos2d, I would gradually move each curve's control points over time until they line-up vertically or horizontally with the curve's origin and destination. This turns the curves into 4 straight lines: a rectangle!
Well, a square to be exact. You'll also have to move the origins and destinations of all 4 curves to form a rectangle that is not a square, but you get the idea I hope?
See these links for additional info:
Bezier Circle math - http://www.cgafaq.info/wiki/Bezier_Circle
cocos2d - ccDrawCubicBezier - http://www.cocos2d-iphone.org/api-ref/2.0.0/_c_c_drawing_primitives_8h.html#a5a391711c0aa611a06167bdd7637571f
cocos2d - schedule: example code - http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:lesson_2._your_first_game#making_things_move
EDIT: added image
d = d value calculated from equation at: http://www.cgafaq.info/wiki/Bezier_Circle
start, control 1, control 2, and end are the 4 points needed to make a cubic bezier curve in cocos2d.
You will have to write the code for this.
You could, for example, create a number of control points that are around the circle. Each of these control points could consist of 3 points. Two points that represent two points on the circle and one point that controls the curve of the line drawn between the two points. Now you animate the motion between the control points on the curve such that they move to become the control points on a rectangle and at the same time animate the motion of the third control point so the edge changes from a curve to a straight line.