create sketchy / wobbly line using 1D perlin noise - c#

Could somebody help me get started with pseudo code or steps to use the 1D perlin noise to draw sketchy/wobbly lines as depicted in the page
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
(source: virgin.net)
I did find that aforge.net has functions for 1D and 2D perlin noise functions. It shows an example ofusing the 2D noise to generate clouds.
http://www.aforgenet.com/framework/docs/html/f2f36ce1-ddab-389e-b538-0ccaca81fa87.htm
But am not sure how to go about using it to generate wobbly lines.

Only difference you need to make going from 1D to 2D is to calculate the slope. Once you have the slope and the 1D noise, just add that noise in the direction perpendicular to the direction of slope.

I saw your question hoping for pseudocode as an answer. I ended up not using the gradient (I already have a simplex noise function that would be difficult to make compatible) but doing something else.
The idea is to choose an interval length (unity is fine, but larger ones will yield less rounding error) and using a random seed consider the noise interval [s, s + I] where I is the interval length and s is the seed. You then "wrap" it around a circle by mapping an angle theta to I / (2 * Pi) * theta. However, you need to make sure that the noise values of s and s + I are the same, else you would have a discontinuity in the circle. This is easy, however; given x in [s, s + I], just do this:
interpolate(x, s, I)
mid <- noise(s) - noise(s + I)
out <- noise(x)
out <- out + (x - s) / I * mid
out <- out - (s + I - x) / I * mid
return out
Note that if x = s, we subtract mid, and if x = s + I, we add mid.
We now have a mapping from an angle to a noise value. Given the radius we wish our circle to have, we can set the minimum and maximum values of the noise then, for any theta we wish to evaluate, just add the corresponding value to the radius of the circle. In polar coordinates, this looks like:
radius(theta)
s <- randomDouble
I <- 1
theta <- theta / (2 * pi)
dr <- interpolate(theta, s, I)
dr <- dr * (noisemax - noisemin) / 2 + (noisemax + noisemin) / 2
return dr + r
assuming you already have your average radius (r) and the variance you want (noisemin, noisemax), and that your noise function outputs values in [-1, 1]. You will want a tight spread between noisemax and noisemin, else your circle will be mostly wobble.
For a square the process it the same but you do not need any controls or interpolation, just the scaling factors and an interval square side length.
You can get fancy and do a nonlinear interpolation but I don't really see the need, and it might mess up the simplex noise.

Related

Algorithm for finding grid cells contained in arbitrary rotated rectangle (rasterizing)

I'm looking for an algorithm that can compute all grid cells occupied by an arbitrary rectangle in 2d space in a defined area. The rectangle is defined by it's 4 corner coordinates. In the picture below I marked two of them as red, the coordinates of the grid cells are in black. I'm looking for a generic case that also covers unaligned grids (center of grid != center of underlying coodinate system), but converting between Cell coordinates <=> Coordinate system is trivial and already implemented. All cells are squares.
The calculation is done thousands in very short amounts of time and needs to be as fast as possible.
What I'm doing right now:
Right now I'm calculating the edges of the rectangle (AB, BC, CD, DA) and sample them at sampleRate = cellWidth / 4 intervals. To find the middle cells I construct new lines from AB + sampleRate * x to CD + sampleRate * x and sample those lines again at sampleRate. I put all cells that I find at each sampled point into a HashSet to remove duplicates. But I feel this is increadibly inefficient.
I also thought about grabbing all cells in my relevant area into a buffer and generate a range tree or index tree. Then I could queue the bounds of the rectangle and get all contained cells at O(log n+m), but I'm not sure how to implement that and I can't even find any C# range tree implementations.
My knowledge in computer graphics is very rusty, but shouldn't there be an easy geometrical approach that works without sampling?
The points you care about are marked with a dot in the image below. Each point represents either the minimum X value or the maximum X value for a given Y value. For each Y value, the X value is easily calculated from the equation for a line:
x = x0 + (y - y0)(x1 - x0) / (y1 - y0)
Note that an axis-aligned rectangle (where (y1 - y0) is 0) needs to be handled as a special (but trivial) case.
Also note that once you've computed the first X value along an edge of the rectangle, the other X values are equally spaced. The spacing is the inverse of the slope of the line. So the division
M = (x1 - x0) / (y1 - y0)
only needs to be done once, and then repeatedly added to the X value. For example, after calculating the X coordinate for point A in the image, the X coordinate for point B is Bx = Ax + M. And the X coordinate for point C is Cx = Bx + M.
Once you have the min and max X values for each Y value, it's a simple for loop to get all the cells that have that Y value.

How To Calculate angle between 2 lines at intersection

I want to know how to calculate agnle between 2 lines at intersection point.
Please see following image. Here Red line is crossing Green line how can i calculate that angle.?
Calculate the direction vectors of both lines and normalize them:
d := (x2 - x1, y2 - y2)
length = sqrt(d.x^2 + d.y^2)
d := (d.x / length, d.y / length)
Then, you have multiple options to calculate the angle. One simple way is to use the dot product:
dot = dRed.x * dGreen.x + dRed.y * dGreen.y
angle = arc cos(dot)
If you also want to reconstruct angles greater than 180° (you will need correct line orientations then), you need the cross product:
cross = dRed.x * dGreen.y - dRed.y * dGreen.x
angle = atan2(cross, dot)
You can calculate the point of intersection of two lines (if you know the equation of the two lines). Using that point of intersection you can find another point on one of the lines and get the projection of one of the lines onto another. This projection will give you the angle between the two lines.
Also if you know the equation of one of the lines and a point on another line, you can still use this method to find out the angle between the two lines.

How to simulate pendulum movement with high amplitude in C#

I need to make a C# simulator for a simple pendulum.
I have been searching the web for 3 days and I am stuck.
The problem is I have found many equations that would give the angle position as a function of time, which is perfect for my needs for making a visual simulation but the problem is those functions only works for angles smaller than 10, but I should be able to simulate from any angle.
Example of a equation that only works for small angles:
Source: http://hyperphysics.phy-astr.gsu.edu/hbase/pend.html#c2
And the equations that should work for any angle (Amplitude) are too complicated as it involves differential equations, and derivatives. I don't know how to implement these in C#.
Example of a equation that I think would work but I don't know how to use:
Source: http://www.sbfisica.org.br/rbef/pdf/070707.pdf
(Equation number 32)
the problem of this last equation is the "sn" that is Jacobi elliptic function sn(u;m) u, and I don't know how to use in C#
Can someone help? maybe with another equation that I could use programmatically, or helping me understand how I could use this last one if it would really works.
If you want to simulate the pendulum, you don't need the exact solution. The only you need is a sufficiently good approximation at every step of your simulation, combined with sufficient steps. This is similar to approximating a circle with a sufficiently large number of segments, each of them, tangent to the ideal circle.
Now, consider your pendulum has a deviation of theta degrees (or radians) from the vertical as depicted below:
The mass m will have a weight of m * g, where g is the gravity acceleration. Now, let's approximate the angle alpha where the pendulum will move in the next dt seconds (dt is the duration of one step, so dt is just a fraction of a second).
Since the acceleration on the tangent direction is g * cos(theta) we can approximate the tangent distance the pendulum would travel in dt seconds as if the acceleration were constant during this lapse:
d = v * dt + g * sin(theta) (dt)^2 / 2
where v is the tangential speed of the pendulum at the angular position theta. Now we can calculate alpha as
alpha = arcsin(d / r)
where r is the radius. Thus, the only that remains is to update the value of v so we can repeat the same in the next step. Here is how
v := v + g * sin(theta) * dt
Of course, when the pendulum starts you can initialize v = 0.
I haven't tried this myself, so please, let me know if this "simulated" approach worked for you. Good luck!

converting xinput coordinates to a square

i'm working on a small c# program that uses xinput to read the xbox 360 thumb stick.
i have no problem with reading the coordinates and normalizing the values so i get a float between -1 and +1 for X and Y directions.
the problem i have is that the stick itself is physically limited to a circle and in my case i would like to "stretch out" the coordinates so it becomes more of a square than a circle.
the reason is that each direction is controlling a motor and if i move the stick for example top right i would like both X and Y to become 1.
since the stick is circular this is not possible and this also makes it impossible to make both motors run at full speed.
any advice?
So you want a point on a circle of radius r to be mapped to a point on a square of radius r on the same ray through the origin. Toward that goal you have to compute the radius using the usual formula
r = sqrt(x*x+y*y)
and then from that the scale factor
f = r / max ( abs(x), abs(y) )
and in the end replace x by f*x and y by f*y.
One can vary this computation by noting that the factor is
f = sqrt ( 1 + (x*x)/(y*y) )
if abs(y) > abs(x) and
f = sqrt ( 1 + (y*y)/(x*x) )
in the opposite case. Or by noting that the largest coordinate gets replaced by r and the smaller scaled accordingly, which also does not reduce the logistics by much.

slight changes in long lat for varations of point with the same location

Bit of a weird one this. I'm rendering datasets on a map and need to split out points that have exactly the same long and lat. I had the idea of grouping my dataset by long and lat and where they are the same adjusting slightly so that they are visible as seperate entities on the map - rather than overlapping.
I'm using linq to group them and then enumerating my grouped items and I'd like to spiral the adjusted points around the orginal point (this is a requirement as I may have a few hundred points that are the same geographically) so that they spread out from the original point.
Does anyone know of a simple calculation i can add to my loop to adjust the items in this manner.
Thanks,
The math behind this is pretty simple. A circle can be represented by the sine function in the x-axis and the cosine function in the y-axis. Here's some pseudo-code:
int num = OverlappingPoints.Length;
for(int i = 0; i < num; ++i)
{
int radius = 50;
// using 2*pi because most math functions use radians... change 2*pi to 360 if your math library uses 360 degrees instead of 2*pi radians to represent a circle.
Map.Plot(OverlappingPoints[i].Latitude + radius*sin(2*pi*i/num),
OverlappingPoints[i].Latitude + radius*cos(2*pi*i/num));
}
That pseudo-code, if properly implemented, will draw the points out in a circle around the original point. Change the radius multiplier to the sine and cosine functions if you want to increase the radius of the circle. If you want the points to spiral out instead of making a circle, choose a number of points per circle revolution and replace num with that number in the sin/cos functions. Also, increase the radius after each loop iteration, probably by using a number and multiplying it by the loop index. (i.e. you could change radius to 50*i).
Hope this helps.

Categories

Resources