Let's say I have two points P1(x1,y1,z1), and P2(x2,y2,z2).
I want to find P3(x3,y3,z3) between these two points. How can I find P3?
P3 can be anywhere between P1 and P2, hence I cannot use the mid-point formula. Figure shown below
You can use the idea of a weighted average of the two points.
P3 = p * P1 + (1 - p) * P2
or written out
x3 = p * x1 + (1 - p) * x2
y3 = p * y1 + (1 - p) * y2
z3 = p * z1 + (1 - p) * z2
where p is some number between 0 and 1.
So a p of 2/3, would give you a point 2/3 the way starting from P1 toward P2.
Related
I want summation of 3 variables to always equal to a number, in this case 1, but I don't know how to make it happen. For example in the following problem I am trying to find maximum value of "resourceOut/maximumTime" which is a function of x1, x2, x3 but while finding the maximum I want x1, x2, x3 to be equal to 1. (xi is the inital guess value for x1, x2 and R can be any positive number.
function Resource(xi,R)
x = fminsearch(#relations, xi);
x(1)
x(2)
function goldenRatio = relations(xi)
x1 = xi(1);
x3 = xi(2);
x2 = 1 - x1 - x3;
x3 = 1 - x1 - x2;
x1 = 1 - x2 - x3;
R1 = R * x1 * 0.1;
R2 = R * x2 * 0.25;
R3 = R * x3 * 0.50;
T1 = ((((R1)^2)*100)^0.45+1800);
T2 = ((((R2)^2)*100)^0.45+1800);
T3 = ((((R3)^2)*100)^0.45+1800);
elapsedTimes =[T1 T2 T3];
resourceOut = R1 + R2 + R3;
maximumTime = max(elapsedTimes);
goldenRatio = -resourceOut/maximumTime;
end
end
I have game object that moves along a path on a 2D plane, between 2 points (x1,y1) and (x2,y2). Occasionally it gets moved off the path and needs to be put back on it. When this happens I'll know the x-coordinate, but need to calculate the y-coordinate along the path given the x-coordinate.
Here's an illustration of what I mean:
You have a line segment, i.e., the set of all convex combinations of the given endpoints. You would like to find the coefficients that yield the convex combination (x3,y3), where y3 is unknown.
t (x1,y1) + (1-t) (x2,y2) = (x3,y3)
Since x3 is known, we obtain
t = (x3 - x2) / (x1 - x2)
and, thus,
y3 = ((x3-x2) y1 + (x1-x3) y2) / (x1 - x2)
The general equation of a line in 2D is a.x + b.y + c = 0 where the vector U = (-b, a) is a direction vector of the line.
Because (x1, y1) and (x2, y2) are on the line, you know that:
a.x1 + b.y1 + c = 0
a.x2 + b.y2 + c = 0
(x2-x1, y2-y1) is a direction vector of the line so:
-b = x2-x1 and a = y2-y1
So one equation of your line ax + by + c = 0 with :
a = y2-y1
b = x1-x2
c = -a.x1 - b.y1 = x1(y1-y2) + y1(x2-x1)
Knowing a, b, c and x3, you can easily find y3:
y3 = -(c + a.x3) / b
Pay attention nevertheless to the case where b = 0 (case of a vertical line)
How to find an point where line1 and lin2 intersect, if both lines are defined by x,y,alpha where x,y are coordinates of a point on a line and alpha is the angle between the line and x=const?
I tried applying sine theorem but it yields two answers (triangles can be built on both sides of a line). I can check which point forms correct slope with one of the points, but that is ugly.
I can switch to y=ax+b representation, but then I have special cases that I have to worry about. Vertical and horizontal lines should be differently to avoid division by zero in 1/sin(alpha) and 1/cos(alpha) cases.
I am not looking for an implementation in a certain language, just a formula.
These questions are not relevant because they deal with finite line segments, NOT lines.
Given two points and two vectors, find point of intersection
How do you detect where two line segments intersect?
Suppose line 1 is defined by [x1, y1] and alpha1 and line 2 by [x2, y2] and alpha2.
Suppose k1 = tan(alpha1) and k2 = tan(alpha2).
Then the formula for the x-coordinate of the intersection is
x = (y2 - y1 + k1 * x1 - k2 * x2) / (k1 - k2)
Note: Function tan is undefined for angles pi / 2 + k * pi (where k is an arbitrary integer), so:
if k1 is undefined, then x = x1 and y = y2 + k2 * (x1 - x2)
if k2 is undefined, then x = x2 and y = y1 + k1 * (x2 - x1)
(both are practically the same with exchange of indices 1 <--> 2).
For a line equation Y = aX + b, you can calculate a = tan(alpha).
So if line1 is defined as x, y and alpha, the equation is Y = tan(alpha) * X + b.
Now to find b, you need a point on your line. This point has coordinates (x, y).
y = ax + b
b = y - ax
So you line equation is:
Y = tan(alpha) * X + (y - tan(alpha) * x)
Now you only have to solve the lines equation:
Y = a1 * X + b1
Y = a2 * X + b2
Which is:
a1 * X + b1 = a2 * X + b2
(a1 - a2) * X = b2 - b1
X = (b2 - b1) / (a1 - a2)
Right now you can calculate Y too.
So if we replace, we obtain:
X = ((y2 - tan(alpha2) * x2) - (y1 - tan(alpha1) * x1)) / (tan(alpha1) - tan(alpha2)
Simplified:
X = (y2 - y1 - tan(alpha2) * x2 + tan(alpha1) * x1)) / (tan(alpha1) - tan(alpha2)
And then:
Y = tan(alpha1) * X + (y - tan(alpha1) * x
I am trying to solve some equations using a while loop. I have a known and fixed output. Workflow is as follows:
P = 100; %Desired output
x = 1; %Initial guess
while abs(something) > 1e-6
x1 = (25 * x)/2
x2 = 10x - x1
x3 = 20x - (x - x1 - x2)*2
x4 = (x - x1 - x2 -x3)*12
x5 = (x - x1 - x2 -x3) * 10 + x4
P1 = 2005x3
P2 = 1500x5
Pnew = P1 + P2
end
I was hoping to calculate x1, x2, ..., x5 and stop looping when the condition P = Pnew is reached. Due to my modest knowledge of MATLAB any help would be appreciated.
Many thanks in advance.
APPENDIX: Perhaps i didn't explained well. My goal was to stop looping when the condition P = Pnew is achieved. I have a known value P and initial value of x. Pnew should be generated through a given series of equations. When the condition is met x, x1, x2, ..., x5 will have their values. So x is not only the initial value for calculating other unknowns (x1, x2, ..., x5). I tried to modify it but got NaN Pnew, P1, error and inf for P2, x, ...
P = 100; %Desired output
x = 1; %Initial guess
Pnew = P + 1
while abs(P - Pnew) > 1e-6
x1 = (25 * x)/2;
x2 = 10*x - x1;
x3 = 20*x - (x - x1 - x2)*2;
x4 = (x - x1 - x2 -x3)*12;
x5 = (x - x1 - x2 -x3) * 10 + x4
P1 = 2005 * x3;
P2 = 150 * x5;
Pnew = P1 - P2;
error = abs(P - Pnew);
x_new = x - .001 * error;
x = x_new;
end
Your code will error out if you don't use * to multiply. I have fixed the code below for you. The something you are looking for is P - Pnew. This is because you are trying to find the difference and making sure it is over 1e-6 to continue the loop.
Since you need Pnew, you should also do an initial calculation for it. You should note that your calculation doesn't actually make Pnew converge to P.
P = 100; %Desired output
x = 1; %Initial guess
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
while abs( P - Pnew ) > 1e-6
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
end
You should probably also put ; to terminate the line to suppress the output of the calculation.
A do-while loop here would work, but Matlab doesn't have one. You can use encapsulation to hide the code duplication or use a for loop as follows as well.
P = 100; %Desired output
x = 1; %Initial guess
for i = 1:Inf
x1 = ( 25 * x ) / 2
x2 = 10 * x - x1
x3 = 20 * x - ( x - x1 - x2 ) * 2
x4 = ( x - x1 - x2 -x3 ) * 12
x5 = ( x - x1 - x2 -x3 ) * 10 + x4
P1 = 2005 * x3
P2 = 1500 * x5
Pnew = P1 + P2
if abs( P - Pnew ) < 1e-6
break;
end
end
To set a predefined iteration termination in case you have an infinite loop, you can replace i = 1:Inf with i = 1:iterMax where iterMax is the number of max iterations.
Usually in numeric calculations one does not test for equality as the computers cannot distinguish all real numbers. Your condition is actually satisfying for something == P - Pnew
In code it would look like this
P = 100; % Desired output
x = 1; % Initial guess
Pnew = P + 1; % Something far off, just to get through the first check
MAX_ITERATION_COUNT = 10000; % a reasonable upper bound to your loop
loopCount = 0;
while abs(P - Pnew) > 1e-6 && loopCount < MAX_ITERATION_COUNT
loopCount = loopCount + 1;
x1 = (25 * x) / 2;
x2 = 10 * x - x1;
x3 = 20 * x - (x - x1 - x2) * 2;
x4 = (x - x1 - x2 - x3) * 12;
x5 = (x - x1 - x2 - x3) * 10 + x4;
P1 = 2005 * x3;
P2 = 1500 * x5;
Pnew = P1 + P2;
end
This should work for your problem.
EDIT: I added a loop counter in case you're loop does not finish regularly.
I want to write a program which will calculate the statistic in Bertrand paradox.
In my way, I want select two dot in circle , and pass line using them (two dots), it is my chord. Then I want to calculate how many of these chords are longer than sqrt(3); but when I run this script some of the chords are bigger than 2 ! ( radius of my circle is 1 )
I don't know what is wrong with it, can anybody help me?
See this link please for the formula used.
r1 = rand(1,1000000);
teta1 = 2*pi * rand(1,1000000);
x1 = r1 .* (cos(teta1));
y1 = r1 .* (sin(teta1));
r2 = rand(1,1000000);
teta2 = 2*pi * rand(1,1000000);
x2 = r2 .* (cos(teta2));
y2 = r2 .* (sin(teta2));
%solve this equation : solve('(t*x2 +(1-t)*x1)^2 +(t*y2 +(1-t)*y1)^2 =1', 't');
t1= ((- x1.^2.*y2.^2 + x1.^2 + 2*x1.*x2.*y1.*y2 - 2*x1.*x2 - x2.^2.*y1.^2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2).^(1/2) - x1.*x2 - y1.*y2 + x1.^2 + y1.^2)/(x1.^2 - 2*x1.*x2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2);
t2= -((- x1.^2.*y2.^2 + x1.^2 + 2*x1.*x2.*y1.*y2 - 2*x1.*x2 - x2.^2.*y1.^2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2).^(1/2) + x1.*x2 + y1.*y2 - x1.^2 - y1.^2)/(x1.^2 - 2*x1.*x2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2);
length = abs (t1-t2) * sqrt (( x2-x1).^2 + (y2-y1).^2);
hist(length)
flag = 0;
for check = length
if( check > sqrt(3) )
flag = flag + 1;
end
end
prob = (flag/1000000)^2;
Your formula for length is probably to blame for the nonsensical results, and given its length, it is easier to replace it than to debug. Here is another way to find the length of chord passing through two points (x1,y1) and (x2,y2):
Find the distance of the chord from the center
Use the Pythagorean theorem to find its length
In Matlab code, this is done by
distance = abs(x1.*y2-x2.*y1)./sqrt((x2-x1).^2+(y2-y1).^2);
length = 2*sqrt(1-distance.^2);
The formula for distance involves abs(x1.*y2-x2.*y1), which is twice the area of the triangle with vertices (0,0), (x1,y1), and (x2,y2). Dividing this quantity by the base of triangle, sqrt((x2-x1).^2+(y2-y1).^2), yields its height.
Also, putting 1000000 samples into mere 10 bins is a waste of information: you get a crude histogram for all that effort. Better to use hist(length,100).
Finally, your method of selecting two points through which to pass a line does not take them from the uniform distribution on the disk. If you want uniform distribution over the disk, use
r1 = sqrt(rand(1,1000000));
r2 = sqrt(rand(1,1000000));
because for a uniformly distributed point, the square of the distance to the center is uniformly distributed in [0,1].
Finally, I've no idea why you square in prob = (flag/1000000)^2.
Here is your code with aforementioned modifications.
r1 = sqrt(rand(1,1000000));
teta1 = 2*pi * rand(1,1000000);
x1 = r1 .* (cos(teta1));
y1 = r1 .* (sin(teta1));
r2 = sqrt(rand(1,1000000));
teta2 = 2*pi * rand(1,1000000);
x2 = r2 .* (cos(teta2));
y2 = r2 .* (sin(teta2));
distance = abs(x1.*y2-x2.*y1)./sqrt((x2-x1).^2+(y2-y1).^2);
length = 2*sqrt(1-distance.^2);
hist(length,100)
flag = 0;
for check = length
if( check > sqrt(3) )
flag = flag + 1;
end
end
prob = flag/1000000;