If I draw a line from let's say: (2,3) to (42,28), how can I get all points on the line in a Point list? I tried using the slope, but I can't seem to get the hang of it.
To be clear: I would like all the pixels that the line covers. So I can make the line 'clickable'.
This is a math question. The equation of a line is:
y = mx + c
So you need to figure out the gradient (m) and the intercept (c) and then plug in values for x to get values for y.
But what do you mean by "all the points on a line"? There is an infinite number of points if x and y are real numbers.
You can use the formula (x-x1)/(x1-x2) = (y-y1)/(y1-y2). And you know the points with x values ranging from 2 to 42 are on the line and their associated y values have to be found. If any of the resulting y value is not an integer then it should be approximated rightly. And if two consecutive y values differ by more than 1 then the missing y values should be mapped to the last x value.
Here is the pseudo code (tried to capture the crux of the algorithm)
prevY = y1
for(i=x1+1;i<=x2;++i)
{
y = computeY(i);
if(diff(y,prevY)>1) dump_points(prevY,y,i);
prevY = y;
dump_point(i,y);
}
dump_points(prevY,y2,x2);
I am probably not covering all the cases here (esp. not the corner ones). But the idea is that for one value of x there would could be many values of y and vice versa depending on the slope of the line. The algorithm should consider this and generate all the points.
Related
This is more of a general Maths question (might be silly even). But in high school we learn to identify the roots of an equation via it's plot right.
For example, for the equation
y = x^2 - 1
The blue line would show us the roots. This is when the blue line crosses x, so +- 1.
Now, if we said that the equation had a real and an imaginary part, so that it is
y = x^2 - 1 + (x^2 - 0.5)i
as given in the Mathematica screenshot, then we have a real part which crosses zero, and an imaginary part which also crosses zero but at a different x. So my question is: is it possible to identify the roots of such an equation by simply looking at the real and imaginary parts of the plot?
Note: part of my confusion is that if I use FindRoot, in Mathematica, I get either 0.877659 - 0.142424i or -0.877659 + 0.142424i. So might be some fundamental property in Maths I don't know about which prevents one from identifying roots of a complex function through separating real and imaginary parts...
we have a real part which crosses zero, and an imaginary part which also crosses zero but at a different x.
Those are graphs of the real and imaginary parts plotted for real values of x. If they both crossed the horizontal axis at the same point(s), that would mean the equation has real root(s), since both real and imaginary parts would be zero for some real value of x. However, this equation has no real roots, so the crossing points are different.
So my question is: is it possible to identify the roots of such an equation by simply looking at the real and imaginary parts of the plot?
f(x) = x^2 - 1 + i (x^2 - 0.5) is a complex function of a complex variable, which maps a complex variable x = a + i b to the complex value f(x) = Re(f(x)) + i Im(f(x)).
Each of Re(f(x)) and Im(f(x)) is a real function of a complex variable. Such functions can be plotted in 3D by representing x = a + i b as a point in the (a, b) plane, and the value of the function along the third dimension, say c. For example, f(x) has the following graphs for the real and imaginary parts.
The cross-sections of the two surfaces by the horizontal plane c = 0 are pairs of curves where each function is zero, respectively. It follows that the intersections of those curves are the points where Re(f(x)) = Im(f(x)) = 0, which means they are the roots of the equation f(x) = 0.
Since f(x) = 0 is a quadratic equation, it must have two roots, and those two points are in fact ±(0.877659 - 0.142424 i), as can be verified by direct calculation.
I want to plot a function in scilab in order to find the maximum over a range of numbers:
function y=pr(a,b)
m=1/(1/270000+1/a);
n=1/(1/150000+1/a);
y=5*(b/(n+b)-b/(m+b))
endfunction
x=linspace(10,80000,50)
y=linspace(10,200000,50)
z=feval(x,y,pr)
surf(x,y,z);
disp( max(z))
For these values this is the plot:
It's obvious that increasing the X axis will not increase the maximum but Y axis will.
However from my tests it seems the two axis are mixed up. Increasing the X axis will actually double the max Z value.
For example, this is what happens when I increase the Y axis by a factor of ten (which intuitively should increase the function value):
It seems to increase the other axis (in the sense that z vector is calculated for y,x pair of numbers instead of x,y)!
What am I doing wrong here?
With Scilab's surf you have to use transposed z if comming from feval. It is easy so realize if you use a different number of points in X and Y directions, as surf will complain about the size of the third argument. So in your case, use:
surf(x,y,z')
For more information see the help page of surf.
Stephane's answer is correct, but I thought I'd try to explain better why / what is happening.
From the help surf page (emphasis mine):
X,Y:
two vectors of real numbers, of lengths nx and ny ; or two real matrices of sizes ny x nx: They define the data grid (horizontal coordinates of the grid nodes). All grid cells are quadrangular but not necessarily rectangular. By default, X = 1:size(Z,2) and Y = 1:size(Z,1) are used.
Z:
a real matrix explicitly defining the heights of nodes, of sizes ny x nx.
In other words, think of surf as surf( Col, Row, Z )
From the help feval page (changed notation for convenience):
z=feval(u,v,f):
returns the matrix z such as z(i,j)=f(u(i),v(j))
In other words, in your z output, the i become rows (and therefore u should represent your rows), and j becomes your columns (and therefore v should represent your columns).
Therefore, you can see that you've called feval with the x, y arguments the other way round. In a sense, you should have designed pr so that it should have expected to be called as pr(y,x) instead, so that when passed to feval as feval(y,x,pr), you would end up with an output whose rows increase with y, and columns increase with x.
Then you could have called surf(x, y, z) normally, knowing that x corresponds to columns, and y corresponds to rows.
However, if you don't want to change your whole function just for this, which presumably you don't want to, then you simply have to transpose z in the call to surf, to ensure that you match x to the columns or z' (i.e, the rows of z), and y to the rows of z' (i.e. the columns of z).
Having said all that, it would probably be much better to make your function vectorized, and just use the surf(x, y, pr) syntax directly.
I have data with very small values between -1 to 1 in X, Y and Z values between -1 to 1 like below
X,Y,Z
-0.858301,-1,1.00916
-0.929151,-1,1.0047
-0.896405,-0.940299,1.00396
-0.960967,-0.944075,1.00035
wireframe(Z~X+Y,data=sol)
Seems wireframe works only with larger values (1, 2, 3...) , How do I plot small values?
wireframe might be use in one of two ways -
With a rectangular data matrix where the values of x and y are implied by the shape of the matrix.
wireframe(matrix(rnorm(100),ncol=5),drape=TRUE)
Or with a dataframe, where the values of x and y are explicit, and here you can use a formula for the relationships between the columns.
df<-expand.grid(x = seq(0,.1,.01), y = seq(0,.1,.01))
df$z<-rnorm(121)
wireframe(z~x*y,data=df,drape=TRUE)
I've found that if you include the line defining the z axis limits, then you can't draw it below 1. But if you take out the defined axis limits, and let R graph it itself, then it works and you can graph small numbers.
Let's say I have a unit vector a = Vector(0,1,0) and I want to add a random spread of something between x = Vector(-0.2,0,-0.2) and y = Vector(0.2,0,0.2), how would I go about doing that?
If I were to simply generate a random vector between x and y, I'd get a value somewhere in the bounds of a square:
What I'd like instead is a value within the circle made up by x and y:
This seems like a simple problem but I can't figure out the solution right now. Any help would be appreciated.
(I didn't ask this on mathoverflow since this isn't really a 'research level mathematics question')
If I read your question correctly, you want a vector in a random direction that's within a particular length (the radius of your circle).
The formula for a circle is: x2 + y2 = r2
So, if you have a maximum radius, r, that constrains the vector length, perhaps proceed something like this:
Choose a random value for x, that lies between -r and +r
Calculate a limit for randomising y, based on your chosen x, so ylim = sqrt(r2 - x2)
Finally, choose a random value of y between -ylim and +ylim
That way, you get a random direction in x and a random direction in y, but the vector length will remain within 0 to r and so will be constrained within a circle of that radius.
In your example, it seems that r should be sqrt(0.22) which is approximately 0.28284.
UPDATE
As 3D vector has length (or magnitude) sqrt(x2+y2+z2) you could extend the technique to 3D although I would probably favour a different approach (which would also work for 2D).
Choose a random direction by choosing any x, y and z
Calculate the magnitude m = sqrt(x2+y2+z2)
Normalise the direction vector (by dividing each element by its magnitude), so x = x/m, y = y/m, z=z/m
Now choose a random length, L between 0 and r
Scale the direction vector by the random length. So x = x * L, y = y * L, z = z * L
I'm trying to design a program that draws graphs given a set of points (x, y), and it also should recognize the curve (straight line, hyperbole, parabola), with only the help of the points.
Is there an algorithm to do that?
You'll need five points if the curve could be a straight line or a conic (hyperbola, parabola, ellipse, circle).
If the five points are collinear, you have a straight line. (Or a degenerate conic? But if you're expecting straight lines, this should indicate a straight line.)
If four are collinear, you have a degenerate conic, given by the line through the four collinear points and any line through the fifth point that is not parallel to the first line.
If three are collinear, you have a degenerate conic, given by the line through the three collinear points and the line through the two other points. (Unless these two lines are parallel, in which case this isn't a conic.)
If no three points are collinear, you have a unique, non-degenerate conic.
To find the equation for this conic (Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0), take a look at this page, specifically the formula in the DETAILS section. Put in your five x and y values, calculate the determinant of the matrix in terms of x and y, and this will give you the formula of your conic. Then see here to figure out what kind of conic you have based on the values of A, B and C.
If you have more than 5 points, pick five points (preferably so no three are collinear), find the conic, and then check that the remaining points lie on the conic.
You can do it by watching the function extreme but is maybe not optimal solution for this problem (i mean a problem in parabola function like that y = sqrt(x*x-1)).
For straight line you can calc y = ax + b by the 2 random point's and check what other points equal this condition, if yes. This is straight line if no you may check a 2 other exceptions or nothing from it. Maybe somone else get solution for next 2 cases?