I want to draw a line that signifies the altitude of a triangle. I know all 3 points of the circle (a, b, c). I want to draw the altitude through a.
I have the following functions to work out the perpendicular gradient of bc
gradient = function(a, b) {
return b.y - a.y / b.x - a.x;
};
perpendicularGradient = function (a, b) {
return -1 / gradient(a, b);
};
I can now get the equation of the line using y = mx + c for line of a with a perpendicular slope of bc and I can work out the y intercept.
function perpendicularLine(vertex, a, b) {
// b = y - m * x
var slope = perpendicularGradient(a, b),
yIntercept = (- slope * vertex.x) + vertex.y;
//how do I find the coordinates of the point on bc to draw a line from vertex
}
I don't know what to do next, i.e. how do I find the coordinates of the point on bc to join the line from a.
From googling about, I know I could use vectors but I have not covered that yet on my maths course and I would prefer to use the equation of a line.
Right, after you have your yIntercept and the slope of the perpendicular line, you need to construct a system of 2 linear equations with 2 unknowns (x0, y0) from the 2 line equations (bc line and line passing through a). The solution to this system is your intersection point along the bc line.
Let a point p along bc, given by the vector equation p = b + t bc, where t is a parameter. You express orthogonality of the altitude and the base by
ap.bc = 0, or (ab + t bc) bc = 0.
This gives
t = -ab.bc/bc²
which allows you to compute p.
Related
How do I find the two opposite x coordinates at the edge of a circle for a specific y coordinate?
A y coordinate of zero means the center of the circle so the two x coordinates would be +- radius
A y coordinate equaling the radius would give two x coordinates of zero.
I'm using Javascript but any language solution is fine.
Assuming you're talking about circle placed at (0,0) (described by equation x²+y²=R²) and you need to return pair of (symmetric) x coordinates based on y and R, that would be something, like:
const getX = (y, R) => [1, -1].map(n => n*(R**2-y**2)**0.5)
Following is a quick proof-of-a-concept live-demo:
const getX = (y, R) => [1, -1].map(n => n*(R**2-y**2)**0.5)
console.log(getX(0,1))
console.log(getX(1,1))
console.log(getX(-1,1))
console.log(getX(0.7071,1))
.as-console-wrapper{min-height:100%;}
If arbitrary circle center ((x0,y0)) is considered ((x-x0)²+(y-y0)²=R²), more generic solution should work:
const getX = (y, R, x0, y0) => [1, -1].map(n => n*(R**2-(y-y0)**2)**0.5+x0)
The existing answer though technically correct is hugely inefficient. The pattern used creates 2 Arrays every call, and repeats the full calculation twice even though the second result is a simple negative of the first (2 rather than 1 square root operations).
The following is 14 times (1400%) faster
const circleXForY = (y, r) => [y = (1 - (y / r) ** 2) ** 0.5 * r, -y];
If you include the fact that the result can also be NaN when y > r then the above function is a staggering 196 times (19,600%) quicker when y > r || y < -r.
A further slight improvement is to just use the positive result
const circleXForY = (y, r) => (1 - (y / r) ** 2) ** 0.5 * r;
The reason I posted a faster version is that this function is very often used when scanning lining circles for graphical like content presentation. I such cases performance is critical.
find midpoint M of an path arc from A to B:
diagram:
i have :
point A(x,y)
point B(x,y)
radius of the arc
i tried following code but getPointAtLength is deprecated.
var myarc = document.getElementById("myarc");
// Get the length of the path
var pathLen = myarc.getTotalLength();
console.log(pathLen);
// How far along the path to we want the position?
var pathDistance = pathLen * 0.5;
console.log(pathDistance);
// Get the X,Y position
var midpoint = myarc.getPointAtLength(pathDistance)
console.log(myarc.getAttribute("d"));
console.log(midpoint);
Geometric calculation:
Сalculalate vector
AB = B - A (AB.x = B.x - A.x, similar for Y)
It's length
lAB = sqrt(AB.x*AB.x + AB.y*AB.y)
Normalized vector
uAB = AB / lAB
Middle point of chord
mAB = (A + B)/2
Arrow value
F = R - sqrt(R*R - lAB*lAB/4)
Now middle of arc:
M.x = mAB.x - uAB.Y * F
M.y = mAB.y + uAB.X * F
Note that there are two points (you need to know circle center orientation relatice to AB), for the second one change signs of the second terms
Consider the given image of the soccer field
As you can see in the image the various ball movements, some of them are curved(i.e. in case of (1), (2), (3) in the image)) and some may not(i.e a line(4)),
so I need to find the intersection points of ball path with goalline and sideline. Sometimes the input may not be a curve(i.e a line) like in case of (4) given image
I have written a program, I have no clue what is wrong - is this right way to solve this kind of program.
if yes then, how to convert bezier curve into an equation for better solving
considering the given as
beizer curve eqaution -> a(x*x) + b*x + c
and line segment equation -> y = y1 + m(x-x1)
//maxCurvedPoint is the topmost of the curve
var getIntersectionPoint = function (room, ballFromPosition, ballToPosition, maxCurvePoint)
{
var linepoints = [[m1,n1], [m2, n2], [m3, n3], [m4, n4]];
//converting three points(ballFromPosition, maxCurvePoint, ballToPosition) into the quadratic equation (Bezier curve) --(1)
//getting the equation of the line segment using the linepoints --(2)
//equating (1) and (2) and getting a quadratic equation and solving and finding intersection points
return intersectionPoint;
}
// solves //(-b(+-)sqrt(b*b - 4ac)/2ac)
function solve(a, b, c)
{
//check curve intersects line or not
if((Math.pow(b, 2) - (4 * a * c)) >= 0)
{
result1 = (-1 * b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
result2 = (-1 * b - Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a);
return [result1, result2];
}
return [];
}
Can anyone help me with this? Also is the most curve point can be called vertex of the curve?
I find it easier to work with vector equations since the algebra will be rotation-invariant (hence you don't have to re-write the code to deal with e.g. a "horizontal" parabola).
1. Curve representation + Intersection test
Consider a quadratic Bezier curve with endpoints A, C, control point B and parameter t:
And an infinite line with source O, direction D and parameter s:
Equating P and R give a pair of quadratic simultaneous equations, which can be re-arranged to eliminate s and find the parabolic parameter t:
Solve this quadratic equation for t, and only accept real roots in the range [0, 1]. This ensures that any intersection point is always on the segment itself.
2. Dealing with line segments
You can also restrict the intersection point to a line segment, by computing s from t using the equations above, and limiting its value - which equals the distance along the line from O if D is normalized.
3. Computing the control point B
Note that a general value of the control point B will not give a symmetrical parabola. To compute B for a general symmetric curve:
Defining the variables:
M: midpoint of AB
n: clockwise normal to the direction AC
q: signed bulge distance - absolute value is the distance from M to the midpoint of the curve
k: signed distance from M to B
A surprisingly simple result.
4. Sample C# (-style) code
public static Vector2[] computeIntersection
(
Vector2 A, Vector2 C, double q, // parabola segment
Vector2 O, Vector2 P // line segment
)
{
// quadratic solve
double[] solve(double a, double b, double c)
{
double d = b * b - 4.0 * a * c;
if (d < 0.0) // imaginary roots - no intersection at all
return null;
if (d > 0.0) // two distinct real roots
{
double sd = Math.Sqrt(d);
return new double[2] { (-b + sd) / (2.0 * a),
(-b - sd) / (2.0 * a) };
}
else // only one (line segment is tangent to curve)
{
return new double[1] { -b / (2.0 * a) };
}
}
// cross product (in-case undefined)
double cross(Vector2 i, Vector2 j)
{
return i.x * j.y - i.y * j.x;
}
// validity check for t and s
bool valid(double v)
{
return (v >= 0.0) && (v <= 1.0);
}
// compute control point B
Vector2 E = C - A;
Vector2 M = 0.5 * (A + C);
Vector2 N = (new Vector2(E.y, -E.x)).normalize();
Vector2 B = M + (2.0 * q) * N;
// solving for t
Vector2 D = P - O;
bool useX = Math.Abs(D.X) > Math.Abs(D.Y);
double[] T = solve(cross(A + C - 2.0 * B, D),
cross(B - A, D) * 2.0,
cross(A - O, D));
if (T == null) return null;
Vector2[] I = new Vector2[2];
int c = 0;
for (int i = 0; i < T.Length; i++)
{
// check if t is within curve range
double t = T[i];
if (!valid(t)) continue;
// solve for s and check if is within line range
double u = (1 - t) * (1 - t);
double v = 2 * t * (1 - t);
double w = t * t;
double s = useX ? ((u * A.X + v * B.X + w * C.X - O.X) / D.X)
: ((u * A.Y + v * B.Y + w * C.Y - O.Y) / D.Y);
if (!valid(s)) continue;
// compute the corresponding intersection point
I[c++] = O + s * D;
}
// only return valid solutions
if (c == 0) return null;
Array.Resize(ref I, c);
return I;
}
If you translate and rotate all the endpoints in such a way that the line segment becomes (0, 0)-(d, 0), the problem simplifies.
Let the control points be (Xk, Yk), k= 0, 1, 2. The intersections with the axis X are obtained by solving for t the quadratic equation
Y0 (1-t)² + 2 Y1 t(1-t) + Y2 t² = 0.
The corresponding abscissas are given by
X0 (1-t)² + 2 X1 t(1-t) + X2 t² = 0.
You can check if these belong to the interval [0, d]. Then apply the reverse rotation and translation.
Addendum: intersection of two quadratic Beziers
The vector equation of one of the curves can be written
P = P0 (1 - t)² + 2 P1 t (1 - t) + P2 t²
= P0 + 2 (P1 - P0) t + (P0 - 2 P1 + P2) t².
If you apply the affine change of coordinates such that the reference frame becomes (P0, P1 - P0, P0 - 2 P1 + P2), the equation simplifies to
X = 2t
Y = t²
which is the implicit equation
X² = 4Y.
Now by applying the same transform to the control points of the second curve and plugging the parametric equations in the above, you get a quartic equation in t (square of a quadratic polynomial on one side, quadratic polynomial on the other).
There are closed-form formulas for the roots of a quartic equation, and there can be four of them. After selecting the real roots in [0, 1], you evaluate the t parameter of the first curve and also check membership in [0, 1].
Don't forget to restore the original coordinates.
I have a canvas and I draw 2 points.
I have to draw 2 straight lines from each point. Then we must check whether the point u sees the point v and vice versa.
To know, it is necessary to see if the point v is in the wedge of the point u and vice versa:
-Here V is the wedge of U, so V sees U but U don't see V
-Here V sees U and U sees V
If the 2 points are in the wedge of each one then a segment is drawn between the 2 points.
How can I do that kind of wedge in a canvas javascript?
Cross product of two vectors.
Using the cross product of a line (x1,y1, x2,y2) ax a vector (x2-x1, y2-y1) and a vector from the line start to a point x,y (x - x1, y - y1) will give you a number that is negative if the point is to the left of the line, zero if the point is along the line, and positive if the point is to the right of the line.
Thus for a point to be in the view of the V it has to be to the right of the V's left arm AND to the left of the V's right arm.
A V is described as follows
const v = {
lx : ?, // point on left V
ly : ?,
x : ?, // point of V
y : ?,
rx : ?,
ry : ?,
}
The the following function will return true if V1 can see V2 where v1 and v2 are objects as described above.
function canSee(v1,v2){
const lx = v1.lx - v1.x; // get vector from center to left line end
const ly = v1.ly - v1.y;
const cx = v2.x - v1.x; // get vector from center to v2's center
const cy = v2.y - v1.y;
const rx = v1.rx - v1.x; // get vector from center to right line end
const ry = v1.ry - v1.y;
// get the cross product of left and right arms to the other V's center
const lc = lx * cy - ly * cx;
const rc = rx * cy - ry * cx;
return (lc > 0 && rc < 0); // return true if V2 center is right of
// left arm and left of arm.
// else return false;
}
Using the function you can find out if both can see each other as follows.
if(canSee(v1, v2) && canSee(v2, v1)){ } // both can see each other
else { } //one or none can see the other
It is important that the points are on the correct sides. Left and right is defined when standing at a line start and looking towards the line end
I have two points A and B and a population of points, and I would like to find the distance from each and every point to the line AB.
I first get the slope of the line, and then its Y intercept. And following Distance between point & line, at second 00:48 it states that we need the negative inverse of the slope (number).
I would like a function that takes any number, and returns the negative inverse of it. Something like let inverseOfSlope = getInverse(slope); Please and thanks
getDistance(PointA: Object, PointB: Object, Target: Object)
{
// find slope of the line
let slope = (PointA.y - PointB.y) / (PointA.x - PointB.x)
// find y intercept
let yIntercept = PointA.y + ((-1 * slope) * PointA.x)
// find inverse negative of the slope
let newSlope = -1 * getInverse(slope);
// find new y-intercept
let NewYintercept = PointA.y + ((-1 * newSlope) * PointA.x)
// get point of intersection between the two lines
// by solving the two equations equal to each other
// calculate distance between target and point of intersection
// easy
// return result
}
As 4castle comments "the negative inverse of a number" is a trivial thing with no apparent relevance to your problem. Wikipedia gives the formula you need to compute the distance from a point (x0, y0) to a line defined by two points (x1, y1) and (x2, y2), and that formula is straightforwardly implemented in any language without any need for your getInverse(slope) function.