hell-o guys!
well, I'm playing with random walks. Midpoint displacement gives some nice results, but I would like a random walk without walk loops, like the ones (in yellow) on this screen-hot :
My first idea to deal with that problem is to check for each segment if there is an intersection with all others segments, then to delete the walk loop between the both segments and bind at the interesection point. But for some walks, it would give a strange result, like that one :
where the yellow part is a loop, and we can see that a big part of the walk would be deleted if I do what I said.
Maybe another method would be to check, when the displacement of the midpoint is made, if the segments are interesecting. In case of there is an intersection, get another displacment. But it looks to become very time consuming quickly when the number of subdivisions rises...
So I would like to know if there is a way to avoid these loops
so... it's seems playing with the amplitudes of the random numbers is a good way to avoid overlaps :
the path without displacement is drawn in cyan. I didn't get overlaps with these displacments :
do{
dx = (D>0)? 0.5*sqrt((double)(rand()%D)) - sqrt((double)D)/2. : 0 ;
dz = (D>0)? 0.5*sqrt((double)(rand()%D)) - sqrt((double)D)/2. : 0 ;
}while(dx*dx+dz*dz>D);
where D is the squared distance between the two neibourers of the point we want to displace. The (D>0)? is needed to avoid some Floating Point Exception.
Related
I have two curves. One handdrawn and one is a smoothed version of the handdrawn.
The data of each curve is stored in 2 seperate vector arrays.
Time Delta is also stored in the handdrawn curve vector, so i can replay the drawing process and so that it looks natural.
Now i need to transfer the Time Delta from Curve 1 (Raw input) to Curve 2 (already smoothed curve).
Sometimes the size of the first vector is larger and sometimes smaller than the second vector.
(Depends on the input draw speed)
So my question is: How do i fill vector PenSmoot.time with the correct values?
Case 1: Input vector is larger
PenInput.time[0] = 0 PenSmoot.time[0] = 0
PenInput.time[1] = 5 PenSmoot.time[1] = ?
PenInput.time[2] = 12 PenSmoot.time[2] = ?
PenInput.time[3] = 2 PenSmoot.time[3] = ?
PenInput.time[4] = 50 PenSmoot.time[4] = ?
PenInput.time[5] = 100
PenInput.time[6] = 20
PenInput.time[7] = 3
PenInput.time[8] = 9
PenInput.time[9] = 33
Case 2: Input vector is smaller
PenInput.time[0] = 0 PenSmoot.time[0] = 0
PenInput.time[1] = 5 PenSmoot.time[1] = ?
PenInput.time[2] = 12 PenSmoot.time[2] = ?
PenInput.time[3] = 2 PenSmoot.time[3] = ?
PenInput.time[4] = 50 PenSmoot.time[4] = ?
PenSmoot.time[5] = ?
PenSmoot.time[6] = ?
PenSmoot.time[7] = ?
PenSmoot.time[8] = ?
PenSmoot.time[9] = ?
Simplyfied representation:
PenInput holds the whole data of a drawn curve (Raw Input)
PenInput.x // X coordinate)
PenInput.y // Y coordinate)
PenInput.pressure // The pressure of the pen)
PenInput.timetotl // Total elapsed time)
PenInput.timepart // Time fragments)
PenSmoot holds the data of the massaged (smoothed,evenly distributed) curve of PenInput
PenSmoot.x // X coordinate)
PenSmoot.y // Y coordinate)
PenSmoot.pressure // Unknown - The pressure of the pen)
PenSmoot.timetotl // Unknown - Total elapsed time)
PenSmoot.timepart // Unknown - Time fragments)
This is the struct that i have.
struct Pencil
{
sf::VertexArray vertices;
std::vector<int> pressure;
std::vector<sf::Int32> timetotl;
std::vector<sf::Int32> timepart;
};
[This answer has been extensively revised based on editing to the question.]
Okay, it seems to me that you just about need to interpolate the time stamps in parallel with the points.
I'm going to guess that the incoming data is something on the order of an array of points (e.g., X, Y coordinates) and an array of time deltas with the same number of each, so time-delta N tells you the time it took to get from point N-1 to point N.
When you interpolate the points, you're probably going to want to do it intelligently. For example, in the shape shown in the question, we have what look like two nearly straight lines, one with positive slope, and the other with negative slope. According to the picture, that's composed of 263 points. We could reduce that to three points and still have a fairly reasonable representation of the original shape by choosing the two end-points plus one point where the two lines meet.
We probably don't need to go quite that far though. Especially taking time into account, we'd probably want to use at least 7 points for the output--one for each end-point of each colored segment. That would give us 6 straight line segments. Let's say those are at points 0, 30, 140, 180, 200, 250, and 263.
We'd then use exactly the same segmentation on the time deltas. Add up the deltas from 0 to 30 to get an average speed for the first segment. Add up the deltas for 31 through 140 to get an average speed for the second segment (and so on to the end).
Increasing the number of points works out roughly the same way. We need to look at exactly which input points were used to create a pair of output points. For a simplistic example, let's assume we produced output that was precisely double the number of input points. We'd then interpolate time deltas exactly halfway between each pair of input points.
In the case shown in the question, we start with unevenly distributed inputs, but produce evenly distributed outputs. So the second output point might be an average of the first four input points. The next output point might be an average of three input points (and so on). In many cases, it's likely that neither end-point of a segment in the output corresponds precisely to any point in the input.
That's fine too. We interpolate between two points of the input to figure out the time hack for the starting point of the output segment. Likewise for the ending point. Then we can compute the total time it should have taken to travel between them based on the time delta between the points.
If you want to get fancy, you could use a higher order interpolation instead of linear. That does require more input points per interpolation, but it looks like you probably have plenty to do something like a quadratic or cubic interpolation (in most cases). This is likely to make the most differences at transitions--places the "pen" was accelerating or decelerating quickly. In such an place, linear interpolation can give somewhat misleading results (though, given the number of points you seem to be working with, it may not make enough difference to notice).
As an illustration, let's consider a straight line. We're going to start from 5 input points, and produce 7 output points.
So, the input points are [0, 2, 7, 10, 15], and the associated time deltas are [0, 1, 4, 8, 3].
So, out total distance traveled is 16, and we want our output points to be evenly distributed. So, the distance between output points will be 16/7 = (roughly) 2.29.
So, obviously the first output point and time are both 0. The second output point is 2.29. To compute the output time, we take the entirety of the time to the first input point (0->2), plus .29 / (7-2) * (4-1). That interpolated section gives 1.37, so our first output time delta is 2.37.
The next output point should be at a distance of 4.58. Since the second input segment goes from 2 to 7, our entire second output segment will lie within the second input segment. So, we take 2.29 / (7-2), telling use that this output segment occupies .458 of the input segment. We then multiply that by the time for the second input segment to get the time delta for the second output segment: .458 * (4-1) = 1.374.
[...and it continues on the same way until we reach the end.]
I was looking for an implementation of Generalized Hough Transform,and then I found this website,which showed me a complete implementation of GHT .
I can totally understand how the algorithm processes except this:
Vec2i referenceP = Vec2i(id_max[0]*rangeXY+(rangeXY+1)/2, id_max[1]*rangeXY+(rangeXY+1)/2);
which calculates the reference point of the object based on the maximum value of the hough space,then mutiplied by rangXY to get back to the corresponding position of origin image.(rangeXY is the dimensions in pixels of the squares in which the image is divided. )
I edited the code to
Vec2i referenceP = Vec2i(id_max[0]*rangeXY, id_max[1]*rangeXY);
and I got another reference point then show all edgePoints in the image,which apparently not fit the shape.
I just cannot figure out what the factor(rangeXY+1)/2means.
Is there anyone who has implemented this code or familiared with the rationale of GHT can tell me what the factor rangeXYmeans? Thanks~
I am familiar with the classic Hough Transform, though not with the generalised one. However, I believe you give enough information in your question for me to answer it without being familiar with the algorithm in question.
(rangeXY+1)/2 is simply integer division by 2 with rounding. For instance (4+1)/2 gives 2 while (5+1)/2 gives 3 (2.5 rounds up). Now, since rangeXY is the side of a square block of pixels and id_max is the position (index) of such a block, then id_max[dim]*rangeXY+(rangeXY+1)/2 gives the position of the central pixel in that block.
On the other hand, when you simplified the expression to id_max[dim]*rangeXY, you were getting the position of the top-left rather than the central pixel.
I would like to find the intercept of 2 lines in 3D. How can I check if they really intercept withour calculating the the real 3D coorindate at first. And then how can I calculate the 3D coordinates of that particular point?
Secondly, I understand it is not possible to find intercept points if two lines do not intercept. Thus, I would like to find a way to calculate 3d point which has the minimium distance from both point. I come with two minimium distance requirements:
1. take the shortest distance connecting two points and take the mid point as my result
2. find the shortest perpendicular distance away from both lines
Would anyone can give me some tips on it?
Let the first line be P+u.U and the second Q+v.V, where uppercase letters are 3D vectors.
You want to minimize the (squared) distance, i.e.
D²(u, v) = ((P+u.U) - (Q+v.V))²
Then, deriving on u and v, you get the system of equations
D²'u(u, v) = 2U.D(u, v) = 0
D²'v(u, v) = 2V.D(u, v) = 0
or
U.P + U².u - U.Q - U.V.v = 0
V.P + U.V.u - V.Q - V².v = 0
Solve this linear system of 2 equations in the 2 unknowns u and v, and from these, the closest points.
In the special case that the lines are parallel, the system determinant U²V²-(U.V)² is zero, as one expects (actually it is the square of the cross product (UxV)²). You can set u=0 arbitrarily and solve for v.
Ok so I have a 2d vector of chars that I call a grid. Lets just say its 70 x 30. When the grid is created, it automatically fills each position with 'x'
I have a function that displays the grid. So I call this function and a 70x30 grid of x's is displayed to the console.
I have another function that I want to call to essentially replace the char at certain x,y coordinates of the grid with a different char. The points aren't exactly random/scattered. I'm basically starting from a point on the edge of the grid, and drawing zigzagged lines to another edge. All points are predetermined. Theres a lot of points to plot, so manually doing it seems inefficient.
Here's how I was thinking to do it:
Create a double for loop, width and height, calling them i and j
If i = (a || b || c || d...) && j = (e || f || g..)
And essentially do that tedious process for each possible scenario..
Surely there is a much easier and simpler way lol. Any suggestions will be greatly appreciated. Thanks!
If the points can be pre-determined by having a map (as in for a level editor or otherwised fixed pattern), then make a dictionary of x/y co-ordinates to what the tile becomes. Iterate over the dictionary and do each replacement.
If the points aren't pre-determined but follow a pattern, such as lines or blobs, then write a method that draws the line/blob/whatever and call it over and over. The method decides which tiles to replace and replaces those.
Btw, there's a trick when doing 2D checking and processing like this which is called having a 'delta', for instance xdelta=-1, ydelta=0 is west and xdelta=1, ydelta=1 is northeast. By having a delta you can run a function two, four or eight times with different deltas and it'll move in different directions by just using the delta's directions instead of needing to try all eight directions on its own - the delta can also be used to drive the bounds checking if you want, as you can't go out of bounds in a direction you're not proceeding in for example. Then you can go further and have an enumeration of all directions, functions that invert a direction, that turn a direction 90/45 degrees (if it's enumerated it's very simple, you just add 2 or 1 to the enumeration and return the new direction), etc, making processing very easy now.
So I might have something like
function drawLine(int xstart, int ystart, int xdelta, intydelta)
that starts at xstart,ystart, replaces the tile with O, adds xdelta to x, adds ydelta to y, replaces the tile with O, etc until it falls off the edge.
I wrote this function for filling closed loop, pixvali is declared globally to store the color value of the pixel where the first click will be done (inside the closed loop).
But the problem is that this recursion doesn't terminate when its first *fill(..,..)*get over, and it says stack is overflowed...
void fill(int x,int y)
{
GLfloat pixval[3];
glReadPixels(x,y,1,1,GL_RGB,GL_FLOAT,pixval);
if(pixval[0]==pixvali[0] && pixval[1]==pixvali[1] && pixval[2]== pixvali[2])
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
glFlush();
fill(x-1,y);
fill(x+1,y);
fill(x,y-1);
fill(x,y+1);
}
}
The stack overflows because you are using recursion, and the depth of the recursion is linear in the number of pixels in the shape you're filling.
It may also be that you are trying to fill the shape in the same color as it already is. That is, the current gl color is the same as pixvali. In that case, you'll get infinite recursion.
It's kind of hard to tell from the question, but my guess would be that, you begin going in a loop of pixels.
For example, think that you have only 4 pixels that you need to color (0,0), (0,1), (1,0), (1,1).
You begin coloring (0,0). Then your recursion will enter (1,0) since(-1,0) doesn't need coloring. then (0,0) again since, it's the pixel that is (x-1, y) again and so on.
You need to add some way to mark pixels that have been colored already. But that's just a guess because you can't really see what's going on outside that functions.
Not sure of the implementation details, but if the 12 byte local array is allocated on the stack (3 floats a 4 bytes each), then you have 4 bytes each for the x and y parameters, and probably four bytes for the return address. That gives at least 24 every time you recurse. That means you only need a bit more than 40'000 calls to blow through 1MB of stack space, if there's nothing else on it, which won't be true.
To put that in perspective, 43'690 pixels is only about 10% of an 800x600 display.
You need to check what pixels are you editing.
e.g. If you have an image from 0,0 to 10,10 and you edit 11,10 you will get outside of memory.
So you need to check if x,y is between the boundaries of the image.
x>=left&&x<=right&&y>=top&&y<=bottom
implement your own stack, don't use recursion for flood fill unless you are filling shapes with relatively small surface area in terms of pixels.
a typical implementation is:
Stack stack;
stack.push(firstPoint);
while(!stack.isEmpty()){
Point currentPoint= stack.pop();
//do what ever you want to do here, namely paint.
//boundary check ur surrounding points and push them in the stack if they are inbounds
}
At first glance, the algorithm looks good. I'm a bit worried about the "==" because they don't work well with float values. I suggest to use
abs(val1 - val2) < limit
instead (where limit is < 1 and > 0. Try 0.0001, for example).
To track down the bug, I suggest to add a printf() at the beginning of the function. When you see what the function tries to fill, that will help. Maybe it is stuck somewhere and calls itself again and again with the same coordinates?
Also, the stack may simple be too small for the area you try to fill. Try with a small area first, say a small rectangle only 4 by 3 pixels. Don't try to click it with the mouse but start with a known good point inside (just call fill() in your code).
Also printing the values for the color could help.
Why are you abusing OpenGL for this? What you do there is very unstable. For example the pixel read by glReadPixels will only correspond to the vertex position if a carefully chosen combination of projection and modelview matrix is used. Also every iteration of fill will do a full round trip. Just because you're using OpenGL it doesn't get magically fast.
If you want to flood fill some area in the framebuffer, readout the whole framebuffer, do the floodfill on that and push the result back to OpenGL. Also if some part of the framebuffer is occluded (by a window, or similar), those parts won't be
Now to understand why you end up in a infinite recursion. Consider this:
fill(4, 4) will call fill(5, 4) will call fill(5, 5) will call fill(4, 5) will call fill(4, 4) boom
Now you've got that test there:
if( pixval[0] == pixvali[0] &&
pixval[1] == pixvali[1] &&
pixval[2] == pixvali[2] )
Note that this evaluates true if the to be set pixel already has the target color, again winding up in a endless recursion. You should test for inequality.
Last but not least: A picture may consists of millions of pixels easily. Usual stack sizes allow only for at most a few 1000 function nesting levels, so you'll have convert your tail recursion into a iteration.
TL;DR: Don't use OpenGL for this, operate on a local buffer, use proper iteration condition test and use iteration instead of recursion (or use a functional language, then the compiler will take care of that tail recursion).
http://en.wikipedia.org/wiki/Flood_fill