Please see the image below.
This path object is created using 4 Bezier curve on each side.
Currently I am facing a problem when I try to get bounds of this path object created using cubic brazier curves. As you can see top and bottom sides have control point away from the curve which makes bounds totally inaccurate.
So my question is is it possible to create a jigsaw puzzle piece like in the image having all control points on or at the level of the curve. ( That is creating a curve and perfect mirror of it, all points within the bounds of the curve)
Don't calculate the bounds by using the control points, then. At least if you need tight bounds and don't want a quick check for potential visibility in a given clipping rectangle.
This awesome site can help a lot with common Bézier curve calculations, including bounding box.
Alternatively, switch to splines where the control points are on the curve, but then you could end up with the opposite effect where the curve extends beyond the bounds imposed by its control points.
You can easily convert your BEZIER cubic control points into Interpolation cubic. Just by reversing this:
BEZIER vs. interpolation cubic
so:
/* bezier = interpol
1 | ( x0)=X1;
t | (3.0*x1)-(3.0*x0)=(0.5*(X2-X0));
tt | (3.0*x2)-(6.0*x1)+(3.0*x0)=(3.0*(X2-X1))-(X2-X0)-(0.5*(X3-X1));
ttt|( x3)-(3.0*x2)+(3.0*x1)-( x0)=(0.5*(X2-X0))+(0.5*(X3-X1))+(2.0*(-X2+X1));
1 | ( y0)=Y1;
t | (3.0*y1)-(3.0*y0)=(0.5*(Y2-Y0));
tt | (3.0*y2)-(6.0*y1)+(3.0*y0)=(3.0*(Y2-Y1))-(Y2-Y0)-(0.5*(Y3-Y1));
ttt|( y3)-(3.0*y2)+(3.0*y1)-( y0)=(0.5*(Y2-Y0))+(0.5*(Y3-Y1))+(2.0*(-Y2+Y1));
*/
// input: x0,y0,..x3,y3 ... Bezier control points
// output: X0,Y0,..X3,Y3 ... interpolation control points
double x0,y0,x1,y1,x2,y2,x3,y3,m=1.0/9.0;
X0=x0-(x1-x0)/m; Y0=y0-(y1-y0)/m;
X1=x0; Y1=y0;
X2=x3; Y2=y3;
X3=x3+(x3-x2)/m; Y3=y3+(y3-y2)/m;
Hope I did not make any algebraic mistake. This will move all control points into your curves directly while the shape will be unchanged. Beware that for BBOX computation you should only use (X1,Y1) and (X2,Y2) as the used parameter t=<0,1> is interpolating between them !!!.
But even this can provide inaccuracy as you can have some extremes without control point. In case even that is a problem (The BBOX is a bit smaller than should) you can re-sample your shape to set of points (for example 10 per cubic) on the curve with some step (0.1) and do the BBOX from those points. That will be much more precise but slower of coarse...
One property of Bezier curves is that as you split them, the distance between the smooth curve and the CVs shrinks.
So, one way to fix those CVs on the top and bottom is to split the related Bezier into two Beziers using the De Casteljau algorithm.
You could even do this algorithmically:
Find tight bounding box and CV-based bounding box.
If the difference is greater than your tolerance, find the max/min CVs and their related Bezier curves
Split all of the related Bezier curves into two Bezier curves each
Repeat
Eventually you'll hit your tolerance. You might have a lot of Beziers by then though if you have a very tight tolerance or tricky data.
Related
I'm currently working on my master's thesis where I get:
A Delaunay triangulation drawn for me with given n points in (x, y, z) form.
My task is to use this triangulation and make contour lines at given z values.
I have been nearly successful at doing this by implementing the wikipedia spline interpolation : https://en.wikipedia.org/wiki/Spline_interpolation
My problem is that I get contour lines crossing each other when implementing the splines while of course the linear drawings doesn't cross.
Parametric cubic spline interpolated contour lines
If you look at the bottom part of the screen you see two contour lines crossing, I don't have enough reputation points to show that the linear drawings doesn't. You can also see that from point to point that the edges are way too rounded.
What I've tried is to interpolate more points between any pair of points to make more knot points along the lines, this to restrict them further, but to get non-crossing lines the splines look too much like a linear drawing which isn't satisfactory to the eye.
What I'd like to know, is not actual code implementation of the how, but maybe a pointer to how, readings and so forth.
(NB, I'm going to make this from scratch, no libraries).
Question: How to make a higher degree polynomial function which doesn't curve too much outside its linear counterpart. By too much I mean that a given contour at let's say 50 meters, that it doesn't cross a contour at 60 meters.
Any help is highly appreciated.
You can try a weighted delaunay triangulation. It's defined as the euklidian distance minus the weight.
Couples of years ago I solved similar task.
Here are some of my working notes. Probably it would help you.
Refer to XoomCode AcidMaps plugin, on github:
https://github.com/XoomCode/AcidMaps/tree/master/examples/isolines
Here is a demo:
http://ams.xoomcode.com/flex/index.html
Set, for example, the renderer type "Sparse" and interpolation strategy as "Linear", then press the "Update" button.
Refer to VividSolutions JTS Java library:
http://www.vividsolutions.com/jts/download.htm
http://mike.teczno.com/notes/curves-through-points.html
http://blog.csdn.net/xsolver/article/details/8913390
I am trying to find an algorithm to draw a smooth curve passing through n points in Java.
I read a lot about the subject, but I only find examples with 3 or 4 points. I don't get how I am supposed to generalize the process with more points.
For instance, I found that answer that shows how to make a Bezier curve with 3 points. But if I repeat the process with the 3 next points, the 2 curves will not join smoothly.
I also found this interesting pdf that describes in details the process. The part I'm interested in is the 5th chapter about interpolation by cubic splines. It explains how to achieve what I want, but for 6 points. There isn't a generalization for n points.
If you see an easier approach, I would gladly take it. I just don't want Lagrange interpolation. As shown in the linked pdf, it doesn't give good results...
You can find both short introduction into cubic splines and good practical implementation in this chapter of the book Numerical Methods in C.
You can also use Catmull-Rom splines (they provide smoothness only for the first derivative)
One more simple approach for interpolation with Bezier curves proposed by Maxim Shemanarev
You did not mention what means smooth for you (what continuity c0,c1,c2...?) but in most cases for visual smoothness cubics are enough (4 point curves).
If you want your curve going through all the points then you want interpolation instead approximation so BEZIER/SPLINE is not a way (unless some additional computations are introduced).
So your question boils to 2 things. What polynomial curve to use and how to smoothly join more of them together. To achieve that you need to sequence the control points in a specific manner. Booth of these questions are answered here:
Proper implementation of cubic spline interpolation
The interpolation polynomial used there is constructed in a way that it goes through all control points and 1st derivation is smoothly connected on both ends if more such curves are put together. The point call sequence is the same as for BEZIER/SPLINE cubics.
If you want/need to use BEZIER instead interpolation (for example to use GDI for rendering it) and still want the curve going through all the points you can convert that interpolation cubics of mine into BEZIER (it is form of Catmull-Rom splines) you just convert the control points into new ones so BEZIER matches the same shape. It is easily done like this:
how to convert interpolation cubic polynomial to cubic BEZIER
Here you can find example images how the joined curves looks like
SVG Paths and the Catmull-Rom algorithm
I played around with the JTS Topology Suite which looks quite nice.
However, I couldn't manage to resolve the collision between two Geometry instances. I would like to perform a wall sliding between Geometry A and B (see screenshot below).
I tried to implement the solution posted in this comment (Solution 2):
https://gamedev.stackexchange.com/questions/104099/how-to-go-about-an-intermediate-collision-resolution-system/104105#104105
However, I couldn't manage to calculate a raycast or even calculate the normal of B's border vector which A collides.
Would someone give me a starting point of how to implement a wall sliding using JTS?
How to do a raycast along the motion vector (calculate the collision position of two Geometry instances)?
How to calculate the collision normal?
EDIT: The Geometry class provides to methods which might help me "intersects" and "intersection". "intersects" returns true if the argument geometry interects this geometry. "intersection" returns a Geometry representing the point-set which is common to both Geometries. Maybe I could use "intersection" to find the first collision point.
Has anyone done this with the JTS? Maybe the suite already provides algorithm to perform this task.
Thanks in advance
Raycasting means you define a starting point as well as a direction and calculate in infinite length vector (ray). Then you calculate where that ray would hit an object.
In your case the ray direction would be your motion vector, the starting point would depend on the shape of your geometry/bounding shape. In case of a bounding box you could cast multiple rays from each of the corners and check which hits the obstacle first. Of course this wouldn't work correctly if the box would hit the obstacle's corner etc. However this might provide a starting point. Note that efficient and correct collision detection is a really complex topic.
As for your second question: IIRC the collision normal is the average of the motion vector and projection of the motion vector onto the collision surface. The weight of each vector would depend on movement speed and surface properties, e.g. bounciness. Again quite a complex topic and my memory might trick me here (collision normal might as well just be the normal of the collision surface at the point of impact)
Let me try to illustrate the second point with some ascii diagram:
O - moving object
\ - motion vector
\
\ / - collision normal
\ /
___\/__.___________ - collision surface ("average" of motion vector and vector between impact point and the "dot" projected onto the surface)
\ |
\ | - project motion vector from "inside" onto the collision surface (up in this case)
\|
Note that's right off my head which might trick me atm, I'll look up some tutorials/descriptions if I have time.
Some link(s) that might help you get started:
http://simonpstevens.com/articles/vectorcollisionphysics
Collision Normal of two points (this actually suggests the collision normal is the normal of the surface at the point of impact)
i want to find a circular object(Iris of eye, i have used Haar Cascase with viola Jones algorithm). so i found that hough circle would be the correct way to do it. can anybody explain me how to implement Hough circle in Java or any other easy implementation to find iris with Java.
Thanks,
Duda and Hart (1971) has a pretty clear explanation of the Hough transform and a worked example. It's not difficult to produce an implementation directly from that paper, so it's a good place for you to start.
ImageJ provides a Hough Circle plugin. I've been playing around with it several times in the past.
You could take a look at the source code if you want or need to modify it.
If you want to find an iris you should be straightforward about this. The part of the iris you are after is actually called a limbus. Also note that the contrast of the limbus is much lower than the one of the pupil so if image resolution permits pupil is a better target. Java is not a good option as programming language here since 1. It is slow while processing is intense; 2. Since classic Hough circle requires 3D accumulator and Java probably means using a cell phone the memory requirements will be tough.
What you can do is to use a fact that there is probably a single (or only a few) Limbuses in the image. First thing to do is to reduce the dimensionality of the problem from 3 to 2 by using oriented edges: extract horizontal and vertical edges that together represent edge orientation (they can be considered as horizontal and vertical components of edge vector). The simple idea is that the dominant intersection of edge vectors is the center of your limbus. To find the intersection you only need two oriented edges instead of three points that define a circle. Hence dimensionality reduction from 3 to 2.
You also don’t need to use a classical Hough circle transform with a huge accumulator and numerous calculations to find this intersection. A Randomized Hough will be much faster. Here is how it works (~ to RANSAC): you select a minimum number of oriented edges at random (in your case 2), find the intersection, then find all the edges that intersect at approximately the same location. These are inliers. You just iterate 10-30 times choosing a different random sample of 2 edges to settle in a set with maximum number of inliers. Hopefully, these inliers lie on the limbus. The median of inlier ray intersections will give you the center of the circle and the median distance to the inliers from the center is the radius.
In the picture below bright colors correspond to inliers and orientation is shown with little line segment. The set of original edges is shown in the middle (horizontal only). While original edges lie along an ellipse, Hough edges were transformed by an Affine transform to make those belonging to limbus to lie on a circle. Also note that edge orientations are pretty noisy.
I'm calculating shortest path of a robot on a plane with polygonal obstacles. Everything works well and fast, no problems there. But, how to smoothen the path so it becomes curvy ?
Below is a picture of a path connecting vertices with a straight line.
P.S
Robot is just a circle.
This paper might be useful. It looks like it's a non-trivial problem. Abstract:
Automatic graph drawers need to compute paths among ver- tices of a simple polygon which besides remaining in the interior need to exhibit certain aesthetic properties. Some of these require the incorpo- ration of some information about the polygonal shape without being too far from the actual shortest path. We present an algorithm to compute a locally convex region that “contains” the shortest Euclidean path among two vertices of a simple polygon. The region has a boundary shape that “follows” the shortest path shape. A cubic Bezier spline in the region in- terior provides a “short and smooth” collision free curve between the two given vertices. The obtained results appear to be aesthetically pleasant and the methods used may be of independent interest. They are elemen- tary and implementable. Figure 7 is a sample output produced by our current implementation.
I used to play with path calculation techniques a lot when trying to make realistic flying sequences to be rendered in Teragen. I initially tried using Bézier Curves.
But discovered that (for flying at least) they aren't that useful. The reason is that the curvature between curves is discontinuous, and so cannot be used to calculate a continuous correct banking angle for a fly-by. Also, it's hard to be sure that the curve doesn't intersect an mountain.
I digress. The way I eventually settled on was a simple mass-spring based path, and relax it into submission.
Subdivide the path into lots of little segments, the more the merrier. For each point, move it a little bit in a direction so as to reduce the angle between it and its neighbours, and way from the obstacles. Repeat many times until the path has settled down.
k = 0.01 // Adjust the values of k and j to your liking.
j = 0.01 // Small values take longer to settle. Larger values are unstable.
For each point P
normal_vector = vector_to_previous_point + vector_to_next_point
obstacle_vector = vector_to_nearest_obstacle
obstacle_distance = magnitude(obstacle_vector)
obstacle_vector *= obstacle_distance^2
P += (normal_vector * k) - (obstacle_vector * j)
The benefit of these kind of finite element relaxation techniques is that you can program all kinds of constraints into it, and the path will settle on some compromise between them, depending on the weights (j and k in this case).
If you're into robotics, why not come and join the Robotics Proposal?
Can't you just make the path curvy in the actual execution of the path following algorithm? If you leave the path as is (i.e. connected straight lines), implementing a look ahead distance of ~1 meter (this value will depend on the speed of your robot and the amount you've padded the configuration space to avoid obstacles) in the control algorithm that calculates the velocity of each wheel will automatically smooth out the path without any need for preprocessing.
Here's a quick images of what I mean...the red dotted-line is the path that is actually executed by the robot when you control to a point based on a lookahead distance. A lookahead distance just computes a point further down the path by some arbitrary distance.
Again, the only thing you have to worry about is how much you're padding obstacles to make sure you avoid hitting them. Normally I believe the area of an obstacle is padded by half the robot's radius, but if you're controlling to a lookahead distance you may have to make this slightly larger.
In the case of a robot we can't know the future. We have to draw each point knowing only the location of the robot and the obstacles. The usual method for making curved paths of minimum length is to model the robot with a circle and move the circle so it remains in contact with the obstacles. Just keep one radius away and the turns will be curves.
If you want curves and NOT minimum distance try making the above radius proportional to the distance you are from a polygon vertex.
The Bezier curves idea only works to make the path curved in retrospect. It changes where the robot ha been. Usually with robots changing the past is called "cheating". One way to avoid having to change the path you've already walked is to look ahead. But can the robot see around corners? You have to specify the rules better.