I'm trying to get x and y coordinates for points along a line (segment) at even intervals. In my test case, it's every 16 pixels, but the idea is to do it programmatically in ActionScript-3.
I know how to get slope between two points, the y intercept of a line, and a2 + b2 = c2, I just can't recall / figure out how to use slope or angle to get a and b (x and y) given c.
Does anyone know a mathematical formula to figure out a and b given c, y-intercept and slope (or angle)? (AS3 is also fine.)
You have a triangle:
|\ a^2 + b^2 = c^2 = 16^2 = 256
| \
| \ c a = sqrt(256 - b^2)
a | \ b = sqrt(256 - a^2)
| \
|__________\
b
You also know (m is slope):
a/b = m
a = m*b
From your original triangle:
m*b = a = sqrt(256 - b^2)
m^2 * b^2 = 256 - b^2
Also, since m = c, you can say:
m^2 * b^2 = m^2 - b^2
(m^2 + 1) * b^2 = m^2
Therefore:
b = m / sqrt(m^2 + 1)
I'm lazy so you can find a yourself: a = sqrt(m^2 - b^2)
Let s be the slop.
we have: 1) s^2 = a^2/b^2 ==> a^2 = s^2 * b^2
and: 2) a^2 + b^2 = c^2 = 16*16
substitute a^2 in 2) with 1):
b = 16/sqrt(s^2+1)
and
a = sqrt((s^2 * 256)/(s^2 + 1)) = 16*abs(s)/sqrt(s^2+1)
In above, I assume you want to get the length of a and b. In reality, your s is a signed value, so a could be negative. Therefore, the incremental value of a will really be:
a = 16s/sqrt(s^2+1)
The Point class built in to Flash has a wonderful set of methods for doing exactly what you want. Define the line using two points and you can use the "interpolate" method to get points further down the line automatically, without any of the trigonometry.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Point.html#interpolate()
The Slope is dy/dx. Or in your terms A/B.
Therefore you can step along the line by adding A to the Y coordinate, and B to the X coordinate. You can Scale A and B to make the steps bigger or smaller.
To Calculate the slope and get A and B.
Take two points on the line (X1,Y1) , (X2,Y2)
A= (Y2-Y1)
B= (X2-X1)
If you calculate this with the two points you want to iterate between simply divide A and B by the number of steps you want to take
STEPS=10
yStep= A/STEPS
xStep= B/STEPS
for (i=0;i<STEPS;i++)
{
xCur=x1+xStep*i;
yCur=y1+yStep*i;
}
Given the equation for a line as y=slope*x+intercept, you can simply plug in the x-values and read back the y's.
Your problem is computing the step-size along the x-axis (how big a change in x results from a 16-pixel move along the line, which is b in your included plot). Given that you know a^2 + b^2 = 16 (by definition) and slope = a/b, you can compute this:
slope = a/b => a = b * slope [multiply both sides by b]
a^2 + b^2 = 16 => (b * slope)^2 + b^2 = 16 [by substitution from the previous step]
I'll leave it to you to solve for b. After you have b you can compute (x,y) values by:
for x = 0; x += b
y = slope * x + intercept
echo (x,y)
loop
Related
We define the sigmoidal function
σ(t) = 1 / (1+e−t)
It has the derivative σ′(t) = σ(t)(1 − σ(t)). The module gauss_newton contains a function generate_data(gamma=0) which generates a data set (ti , αi ) where ti ∈ R and αi ∈ R with
αi = σ(6ti + 1) + εiγ.
for i = 1, . . . , 10. The values εi ∼ N (0, 1) are independently normally distributed and the real value γ ∈ R controls the influence of εi.
(i) Solve the problem min (1/2(∥F(x)∥^2),
with Fi(x) = σ(x1ti + x2) − αi for i = 1,...,10 and γ = 0 using the Gauss Newton algorithm . Iterate until the size of the search direction is sufficiently small, i.e. until ∥∆xk ∥ < δ for some tolerance δ > 0.
Using Octave's symbolic package, I define a symbolic function of t like this:
>> syms a b c d t real;
>> f = poly2sym([a b c], t) + d * exp(t)
f = (sym)
2 t
a⋅t + b⋅t + c + d⋅ℯ
I also have another function with known coefficients:
>> g = poly2sym([2 3 5], t) + 7 * exp(t)
g = (sym)
2 t
2⋅t + 3⋅t + 7⋅ℯ + 5
I would like to solve f == g for the coefficients a, b, c, d such that the equation holds for all values of t. That is, I simply want to equate the coefficients of t^2 in both equations, and the coefficients of exp(t), etc. I am looking for this solution:
a = 2
b = 3
c = 5
d = 7
When I try to solve the equation using solve, this is what I get:
>> solve(f == g, a, b, c, d)
ans = (sym)
t 2 t
-b⋅t - c - d⋅ℯ + 2⋅t + 3⋅t + 7⋅ℯ + 5
───────────────────────────────────────
2
t
It solves for a in terms of b, c, d, t. This is understandable since in essence there is no difference between the variables b, c and t. But I was wondering if there was a method to somehow separate the terms (using their symbolic form w. r. t. the variable t) and solve the resulting system of linear equations on a, b, c, d.
Note: The function I wrote here is a minimal example. What I am really trying to do is to solve a linear ordinary differential equation using the method of undetermined coefficients. For example, I define something like y = a*exp(-t) + b*t*exp(-t), and solve for diff(y, t, t) + diff(y,t) + y == t*exp(-t). But I believe solving the problem with simpler functions will lead me to the right direction.
I have found a terribly slow and dirty method to get the job done. The coefficients have to be linear in a, b, ... though.
The idea is to follow these steps:
Write the equation in f - g form (which equals zero)
Use expand() to separate the terms
Use children() to get the terms in the equation as a symbolic vector
Now that we have the terms in a vector, we can find those that are the same function of t and add their coefficients together. The way I checked this was by checking if the division of two terms had t as a symbolic variable
For each term, find other terms with the same function of t, add all these coefficients together, save the obtained equation in a vector
Pass the vector of created equations to solve()
This code solves the equation I wrote in the note at the end of my question:
pkg load symbolic
syms t a b real;
y = a * exp(-t) + b * t * exp(-t);
lhs = diff(y, t, t) + diff(y, t) + y;
rhs = t * exp(-t);
expr = expand(lhs - rhs);
chd = children(expr);
used = false(size(chd));
equations = [];
for z = 1:length(chd)
if used(z)
continue
endif
coefficients = 0;
for zz = z + 1:length(chd)
if used(zz)
continue
endif
division = chd(zz) / chd(z);
vars = findsymbols(division);
if sum(has(vars, t)) == 0 # division result has no t
used(zz) = true;
coefficients += division;
endif
endfor
coefficients += 1; # for chd(z)
vars = findsymbols(chd(z));
nott = vars(!has(vars, t));
if length(nott)
coefficients *= nott;
endif
equations = [equations, expand(coefficients)];
endfor
solution = solve(equations == 0);
I have a function
f(x,y,z) = 1 + 2xyz - xx - yy - z*z. My range of interest is [-1,1] in any variable.
Obviously, I could not construct a human visible 4D Plot, but I could plot the points in 3D where it vanishes, or fill with red the range where it is positive.
Having forgotten almost everything about matlab and octave, I searched examples and tried:
[x y z] = meshgrid(-1:0.1:1, -1:0.1:1, -1:0.1:1);
coords = [x(:) y(:) z(:)];
V = 1.0 + 2*x.*y.*z -y.*y - z.*z - x.*x;
for p = 1: 1:100
if V(p) >=0
c = 'red';
scatter3(x(:,p),y(:,p), z(:,p), 'c');
end
end
It produces a plot, but it must be bogus, because there are no red dots and 1,1,1 is a solution, which doesn’t show up in the plot. Also the z axis is messed up, showing only negative values.
Please help.
The Plot:
Try this
[x y z] = meshgrid( -1 : 0.1 : 1, -1 : 0.1 : 1, -1 : 0.1 : 1 );
V = 1.0 + 2 * x .* y .* z - y .* y - z .* z - x .* x;
scatter3( x(:), y(:), z(:), 100, V(:), 'filled' );
Are there any pairs (x,y) such that z = x<<1 and z == y>>1 where x != y?
Suppose we have x=0010 and y=1000
now if we shift left x by 1 and shift right y by 1
i.e, x<<1=0100 and y>>1=0100 so we have same result for both cases that is 0100
So are there any other pairs (x,y) giving same result z ?
If yes then is there any equation to find out such pairs?
#doynax observed:
x << 1 = y >> 1 <=> x * 2 = floor(y / 2)
Using floor(y/2)==y/2 if y is even; floor(y/2)=(y-1)/2 if y is odd, we get two equations:
(even y): x * 2 = y / 2
(odd y): x * 2 = (y-1)/2
Simplifying:
(even y) x * 4 = y
(odd y) x * 4 = y - 1 ==> x * 4 + 1 = y
We remark that x * 2, and therefore x * 4, is an even number.
So any value of x has a corresponding y by the (even y) equation.
Likewise, x * 4 is even, and x * 4 + 1 is odd, so any
value of x has a corresponding y by the (odd y) equation.
So, these values are easy to generate.
Pick any X.
Both X*4 and X*4+1 are valid values for Y.
Z is X*2
This assumes infinite precision integers. If you are working on a real CPU with an N bit word size, values of X>=2^N/4 won't work as a typical shift will lose bits off the top.
Generally left shift of a number is (number^number_of_left_shifts) and right shift of a number is a (number/number_of_right_shifts)
you could try using the below equation,
x^1=y/2
y=2(x^1)
The above equation for only one left shift or right shift try substituting with the number_of_shifts you need
Substitute the a,b values such that it satisfies below equation
a^2=b/4
b=4(a^2)
I have an equation for a parabolic curve intersecting a specified point, in my case where the user clicked on a graph.
// this would typically be mouse coords on the graph
var _target:Point = new Point(100, 50);
public static function plot(x:Number, target:Point):Number{
return (x * x) / target.x * (target.y / target.x);
}
This gives a graph such as this:
I also have a series of line segments defined by start and end coordinates:
startX:Number, startY:Number, endX:Number, endY:Number
I need to find if and where this curve intersects these segments (A):
If it's any help, startX is always < endX
I get the feeling there's a fairly straight forward way to do this, but I don't really know what to search for, nor am I very well versed in "proper" math, so actual code examples would be very much appreciated.
UPDATE:
I've got the intersection working, but my solution gives me the coordinate for the wrong side of the y-axis.
Replacing my target coords with A and B respectively, gives this equation for the plot:
(x * x) / A * (B/A)
// this simplifies down to:
(B * x * x) / (A * A)
// which i am the equating to the line's equation
(B * x * x) / (A * A) = m * x + b
// i run this through wolfram alpha (because i have no idea what i'm doing) and get:
(A * A * m - A * Math.sqrt(A * A * m * m + 4 * b * B)) / (2 * B)
This is a correct answer, but I want the second possible variation.
I've managed to correct this by multiplying m with -1 before the calculation and doing the same with the x value the last calculation returns, but that feels like a hack.
SOLUTION:
public static function intersectsSegment(targetX:Number, targetY:Number, startX:Number, startY:Number, endX:Number, endY:Number):Point {
// slope of the line
var m:Number = (endY - startY) / (endX - startX);
// where the line intersects the y-axis
var b:Number = startY - startX * m;
// solve the two variatons of the equation, we may need both
var ix1:Number = solve(targetX, targetY, m, b);
var ix2:Number = solveInverse(targetX, targetY, m, b);
var intersection1:Point;
var intersection2:Point;
// if the intersection is outside the line segment startX/endX it's discarded
if (ix1 > startX && ix1 < endX) intersection1 = new Point(ix1, plot(ix1, targetX, targetY));
if (ix2 > startX && ix2 < endX) intersection2 = new Point(ix2, plot(ix2, targetX, targetY));
// somewhat fiddly code to return the smallest set intersection
if (intersection1 && intersection2) {
// return the intersection with the smaller x value
return intersection1.x < intersection2.x ? intersection1 : intersection2;
} else if (intersection1) {
return intersection1;
}
// this effectively means that we return intersection2 or if that's unset, null
return intersection2;
}
private static function solve(A:Number, B:Number, m:Number, b:Number):Number {
return (m + Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
private static function solveInverse(A:Number, B:Number, m:Number, b:Number):Number {
return (m - Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
public static function plot(x:Number, targetX:Number, targetY:Number):Number{
return (targetY * x * x) / (targetX * targetX);
}
Or, more explicit yet.
If your parabolic curve is
y(x)= A x2+ B x + C (Eq 1)
and your line is
y(x) = m x + b (Eq 2)
The two possible solutions (+ and -) for x are
x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A)) (Eq 3)
You should check if your segment endpoints (in x) contains any of these two points. If they do, just replace the corresponding x in the y=m x + b equation to get the y coordinate for the intersection
Edit>
To get the last equation you just say that the "y" in eq 1 is equal to the "y" in eq 2 (because you are looking for an intersection!).
That gives you:
A x2+ B x + C = m x + b
and regrouping
A x2+ (B-m) x + (C-b) = 0
Which is a quadratic equation.
Equation 3 are just the two possible solutions for this quadratic.
Edit 2>
re-reading your code, it seems that your parabola is defined by
y(x) = A x2
where
A = (target.y / (target.x)2)
So in your case Eq 3 becomes simply
x = ((m +- Sqrt[4 A b + m^2])/(2 A)) (Eq 3b)
HTH!
Take the equation for the curve and put your line into y = mx +b form. Solve for x and then determine if X is between your your start and end points for you line segment.
Check out: http://mathcentral.uregina.ca/QQ/database/QQ.09.03/senthil1.html
Are you doing this often enough to desire a separate test to see if an intersection exists before actually computing the intersection point? If so, consider the fact that your parabola is a level set for the function f(x, y) = y - (B * x * x) / (A * A) -- specifically, the one for which f(x, y) = 0. Plug your two endpoints into f(x,y) -- if they have the same sign, they're on the same side of the parabola, while if they have different signs, they're on different sides of the parabola.
Now, you still might have a segment that intersects the parabola twice, and this test doesn't catch that. But something about the way you're defining the problem makes me feel that maybe that's OK for your application.
In other words, you need to calulate the equation for each line segment y = Ax + B compare it to curve equation y = Cx^2 + Dx + E so Ax + B - Cx^2 - Dx - E = 0 and see if there is a solution between startX and endX values.