Draw 2 parallel lines - graphics

How can I calculate the points to draw 2 parallel lines.
I know the start and end points for the centre of the parallel lines. To makes thing a little bit harder, it needs to support straight and Bezier curved lines.

The question is vague, but here's a possibility. Hope that helps.
For a segment (x1,y1)-(x2,y2) you can calculate another segment, n pixels away in a direction represented by angle a this way
x1b = x1 + n cos a
y1b = y1 - n sin a
x2b = x2 + n cos a
y2b = y2 - n sin a

Related

Simple bouncing ball in haskell keeps bouncing higher

So, I did a simple simulation of a bouncing ball to learn haskell. The ball is supposed to bounce against the image borders and to be accelerated downward by gravity.
The problem is that the ball is "magically" bouncing higher as time passes. I would expect it to keep the same maximum height instead.
I suspect there is something wrong with bounce and not with move because bounce "teleports" the ball back inside the frame, which is not physically accurate. I tried different way to simulate a correct behavior but could not find anything working right.
What would be a correct way to do this?
Here is the code, running on CodeWorld:
main = simulationOf initial step draw
data World = Ball Point Vector
radius = 40
border = 250 - radius
g = -500
initial (x:y:vx:vy:_) = Ball (400*x - 200, 400*y - 200)
(400*vx - 200, 400*vy - 200)
step t world = bounce (move t world)
move t (Ball (x,y) (vx,vy)) = Ball (x + vx*t, y + vy*t) (vx, vy + g*t)
bounce (Ball (x,y) (vx,vy)) = Ball (nx,ny) (nvx, nvy)
where nx = fence (-border) border x
ny = fence (-border) border y
nvx = if nx /= x then -vx else vx
nvy = if ny /= y then -vy else vy
fence lo hi x = max lo (min hi x)
draw (Ball (x,y) _) = translate x y (solidCircle radius)
This is a well-known artifact of the algorithm you're using to integrate the movement's differential equation.
The "real physics" is (I will only discuss the y component)
∂y/∂t = v(t)
∂v/∂t = g
You model this by a discrete sequence of heights and velocities
yi = yi − 1 + vi − 1 ⋅ Δt
vi = vi − 1 + g ⋅ Δt
This sure resembles the differential equations, just written as difference quotients – but it's not the same thing (except in the limit Δt → 0): in reality, the velocity itself changes during the time step, so it's not quite correct to alter the position just according the constant v value before that time step. Simply ignoring that complication is an approximation called Euler's method, and it's known to suck rather badly.
The much more accurate standard alternative is the fourth-order Runge-Kutta method, give that a try.
n.m.'s points about the bouncing is also valid, though to do it really properly you should calculate the exact time of impact, to neither neglect too much acceleration nor get too much that actually never happened.
Suppose the ball hits the ground exactly in the middle of the quantum of time. In reality (or rather in the frictionless "reality") the absolute value of velocity stays the same in the beginning and in the end of the quantum, but in your model it increases.
One should handle acceleration in bounce. The simplest possible way to do that is to do this:
move t (Ball (x,y) (vx,vy)) = Ball (x + vx*t, y + vy*t) (vx, vy)
step t world = bounce (move t world) t
bounce (Ball (x,y) (vx,vy)) t = Ball (nx,ny) (nvx, nvy)
...
nvy = if ny /= y then -vy else vy + g * t
The velocity won't increase during the bounce.
This is still not entirely accurate, the velocity still creeps up, but slower.

centroid of contour/object in opencv in c?

is there some good and better way to find centroid of contour in opencv, without using built in functions?
While Sonaten's answer is perfectly correct, there is a simple way to do it: Use the dedicated opencv function for that: moments()
http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=moments#moments
It does not only returns the centroid, but some more statistics about your shape. And you can send it a contour or a raster shape (binary image), whatever best fits your need.
EDIT
example (modified) from "Learning OpenCV", by gary bradsky
CvMoments moments;
double M00, M01, M10;
cvMoments(contour,&moments);
M00 = cvGetSpatialMoment(&moments,0,0);
M10 = cvGetSpatialMoment(&moments,1,0);
M01 = cvGetSpatialMoment(&moments,0,1);
centers[i].x = (int)(M10/M00);
centers[i].y = (int)(M01/M00);
What you get in your current piece of code is of course the centroid of your bounding box.
"If you have a bunch of points(2d vectors), you should be able to get the centroid by averaging those points: create a point to add all the other points' positions into and then divide the components of that point with accumulated positions by the total number of points." - George Profenza mentions
This is indeed the right approach for the exact centroid of any given object in two-dimentionalspace.
On wikipedia we have some general forms for finding the centroid of an object.
http://en.wikipedia.org/wiki/Centroid
Personally, I would ask myself what I needed from this program. Do I want a thorough but performance heavy operation, or do I want to make some approximations? I might even be able to find an OpenCV function that deals with this correct and efficiently.
Don't have a working example, so I'm writing this in pseudocode on a simple 5 pixel example on a thorough method.
x_centroid = (pixel1_x + pixel2_x + pixel3_x + pixel4_x +pixel5_x)/5
y_centroid = (pixel1_y + pixel2_y + pixel3_y + pixel4_y +pixel5_y)/5
centroidPoint(x_centroid, y_centroid)
Looped for x pixels
Loop j times *sample (for (int i=0, i < j, i++))*
{
x_centroid = pixel[j]_x + x_centroid
y_centroid = pixel[j]_x + x_centroid
}
x_centroid = x_centroid/j
y_centroid = y_centroid/j
centroidPoint(x_centroid, y_centroid)
Essentially, you have the vector contours of the type
vector<vector<point>>
in OpenCV 2.3. I believe you have something similar in earlier versions, and you should be able to go through each blob on your picture with the first index of this "double vector", and go through each pixel in the inner vector.
Here is a link to documentation on the contour function
http://opencv.itseez.com/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contours#cv.DrawContours
note: you've tagged your question as c++ visual. I'd suggest that you use the c++ syntax in OpenCV 2.3 instead of c. The first and good reason to use 2.3 is that it is more class based, which in this case means that the class Mat (instead of IplImage) does leak memory. One does not have to write destroy commands all the live long day :)
I hope this shed some light on your problem. Enjoy.
I've used Joseph O'Rourke excellent polygon centroid algorithm to great success.
See http://maven.smith.edu/~orourke/Code/centroid.c
Essentially:
For each point in the contour, find the triangle area from the current index polygon xy to the next 2 polygon xy points e.g.: Math.Abs(((X1 - X0) * (Y2 - Y0) - (X2 - X0) * (Y1 - Y0)) / 2)
Add this triangle area to a list TriAreas
Sum the triangle area, and store in SumT
Find the centroid CTx and CTy from this current triangle: CTx = (X0 + X1 + X2) / 3 and CTy = (Y0 + Y1 + Y2) / 3;
Store these 2 centroid values in 2 other lists CTxs CTys.
Finally after performing this with all points in the contour, find the contours centroid x and y using the 2 triangle x and y lists in 5 which is a weighted sum of signed triangle areas, weighted by the centroid of each triangle:
for (Int32 Index = 0; Index < CTxs.Count; Index++)
{
CentroidPointRet.X += CTxs[Index] * (TriAreas[Index] / SumT);
}
// now find centroid Y value
for (Int32 Index = 0; Index < CTys.Count; Index++)
{
CentroidPointRet.Y += CTys[Index] * (TriAreas[Index] / SumT);
}

How to determine whether a point (X,Y) is contained within an arc section of a circle (i.e. a Pie slice)?

Imagine a circle. Imagine a pie. Imagine trying to return a bool that determines whether the provided parameters of X, Y are contained within one of those pie pieces.
What I know about the arc:
I have the CenterX, CenterY, Radius, StartingAngle, EndingAngle, StartingPoint (point on circumference), EndingPoint (point on circumference).
Given a coordinate of X,Y, I'd like to determine if this coordinate is contained anywhere within the pie slide.
Check:
The angle from the centerX,centerY through X,Y should be between start&endangle.
The distance from centerX,centerY to X,Y should be less then the Radius
And you'll have your answer.
I know this question is old but none of the answers consider the placement of the arc on the circle.
This algorithm considers that all angles are between 0 and 360, and the arcs are drawn in positive mathematical direction (counter-clockwise)
First you can transform to polar coordinates: radius (R) and angle (A). Note: use Atan2 function if available. wiki
R = sqrt ((X - CenterX)^2 + (Y - CenterY)^2)
A = atan2 (Y - CenterY, X - CenterX)
Now if R < Radius the point is inside the circle.
To check if the angle is between StartingAngle (S) and EndingAngle (E) you need to consider two possibilities:
1) if S < E then if S < A < E the point lies inside the slice
2) if S > E then there are 2 possible scenarios
if A > S
then the point lies inside the slice
if A < E
then the point lies inside the slice
In all other cases the point lies outside the slice.
Convert X,Y to polar coordinates using this:
Angle = arctan(y/x);
Radius = sqrt(x * x + y * y);
Then Angle must be between StartingAngle and EndingAngle, and Radius between 0 and your Radius.
You have to convert atan2() to into 0-360 before making comparisons with starting and ending angles.
(A > 0 ? A : (2PI + A)) * 360 / (2PI)

Calculate Bezier AABB

I'd like to calculate the AABB (axis aligned bounding box) for a quadratic or bezier curve.
The only way I know how to do this is evaluating a high number of points on the bezier curve, and then use those points to calculate the AABB.
Is there a better way?
Great resource on Bezier curves, and working example of AABB http://pomax.github.io/bezierinfo/#boundingbox
For quadratic curve if you need it, also calculate this using derivatives.
Always avoid iterative methods when closed form is available.
It should be possible by looking for minimum and maximum thanks to the derivative of the curve in parametric form. have a look at this article: http://nishiohirokazu.blogspot.jp/2009/06/how-to-calculate-bezier-curves-bounding.html
The quadratic bezier curve consists of 2 coordinate functions — x(t) and y(t) where.
These functions may have maximum or minimum (the points where x'(t) = 0 and y'(t) = 0) and these points are the boundary points of the aabb.
So the algorithm is:
Imagine x0, y0, x1, y1, x2, y2 are known and calculate the values t(x0, x1, x2) and t(y0, y1, y2) when x'(t) = 0 and y'(t) = 0 respectively.
Calculate both values and check whether they are >= 0 and <= 1. If they are evaluate the points of the quadratic bezier.
Take the first and the last points.
Now you have 4 points (or maybe less), use them to calculate AABB.
By the way:
t(x0, x1, x2) = (x0 - x1) / (x2 - 2 * x1 + x0)
t(y0, y1, y2) = (y0 - y1) / (y2 - 2 * y1 + y0)
You can find the full code here: https://github.com/keyten/Graphics2D/blob/Delta/Core/Curve.Math.js#L295

Find start and end XY coords of perpendicular line calculated from start and end XY coords of baseline

Using the following start and end point coordinate values of a baseline:
X1 = 5296823.36
Y1 = 2542131.23
X2 = 5311334.21
Y2 = 2548768.66
I would like to calculate the start and end coordinates of a pendicular line that intersects the baseline at the mid-point. This intersecting, perpendicular line should extend at a given distance either side of the baseline (e.g. Dist=100).
I would be very grateful if anyone could provide some guidance using simple formulas that can be tranferred to Excel or VB.
Many thanks in advance.
Steps to do:
Find the midpoint of the two coordinates (xmid, ymid)
Find the gradient of the line segment joining the two coordinates (call it m).
The gradient of a line perpendicular to this line is -1/m.
Use this new gradient and the coordinates of the midpoint (xmid, ymid) to find the equation of the perpendicular line (substitute xmid, ymid and -1/m into the equation of a line), call it y = -1x/m + k
Imagine a right angled triangle from xmid, ymid to your target point (r units along the perpendicular line is the hypotenuse). The x component will be X units across, the y component will be (-1X/m + k) units up.
Solve
r^2 = X^2 + (-1X/m + k)^2
to find X. Where you have already found r, m and k in the previous steps.
Substitute the +ve and -ve values of this into y = -1x/m + k to get the y coordinates of your endpoints, and Bob's your Uncle.
It should be relatively straight forward to translate this into any given programming language in a very short space of time but you may need to understand the underlying maths to do so, and as a Maths teacher I'm not going to do your Homework for you.

Resources