I implemented both the naive line drawing algorithm and bresenham algorithm. When I run the program with a 1000 lines, the naive line drawing algorithm is faster than the bresenham algorithm. Could anyone explain why?
Here is my code for both methods
def simpleLine(x1, y1, x2, y2):
dy = y2-y1;
dx = x2-x1;
x = x1
m = dy/dx;
b = y1-m*x1;
if(x1>x2):
x1,x2 = x2,x1
x=x1
while(x<=x2):
y=m*x+b;
PutPixle(win,x,round(y));
x=x+1
'
def BresenhamLine(x1, y1, x2, y2):
dx = abs(x2 - x1)
dy = abs(y2 - y1)
p = 2 * dy - dx
duady = 2 * dy
duadydx = 2 * (dy - dx)
x = x1
y = y1
xend = x2
if(x1 > x2):
x, y,xend = x2, y2,x1
while(x < xend):
PutPixle(win,x,y)
x =x+1
if(p<0):
p = p + 2*dy
else:
y = y-1 if y1>y2 else y+1
p = p+2*(dy-dx)
Bresenham's algorithm was invented for languages and machines with different performance characteristics than your python environment. In particular, low-level languages on systems where floating point math is much more expensive than integer math and branches.
In Python, your simple version is faster even though it uses floating point and rounding, because Python is slow and it executes fewer python operations per pixel. Any difference in speed between single integer or floating point operations is dwarfed by the cost of just doing python stuff.
Related
I've got two points between which im drawing a line (x1,y1 and x2,y2) but i need to know the coordinates of x3,y3 which is gapSize away from point x2,y2. Any ideas on how to solve this problem (the program is written in objective-c if that is helpful at all)?
You can simply calculate the angle in radians as
double rads = atan2(y2 - y1, x2 - x1);
Then you get the coordinates as follows:
double x3 = x2 + gapSize * cos(rads);
double y3 = y2 + gapSize * sin(rads);
Is this what you meant?
Compute the distance between P1 and P2: d=sqrt( (y2-y1)^2 + (x2-x1)^2)
Then x2 = (d*x1 + gapSize*x3) / (d+gapSize)
So x3 = (x2 * (d+gapSize) - d*x1) / gapSize
Similarly, y3 = (y2 * (d+gapSize) - d*y1) / gapSize
Sorry for the math. I didn't try to code it but it sounds right. I hope this helps.
There are many ways to do this. Simplest (to me) is the following. I'll write it in terms of mathematics since I can't even spell C.
Thus, we wish to find the point C = {x3,y3}, given points A = {x1,y1} and B = {x2,y2}.
The distance between the points is
d = ||B-A|| = sqrt((x2-x1)^2 + (y2-y1)^2)
A unit vector that points along the line is given by
V = (B - A)/d = {(x2 - x1)/d, (y2-y1)/d}
A new point that lies a distance of gapSize away from B, in the direction of that unit vector is
C = B + V*gapSize = {x2 + gapSize*(x2 - x1)/d, y2 + gapSize*(y2 - y1)/d}
I've written some code below to check if two line segments intersect and if they do to tell me where. As input I have the (x,y) coordinates of both ends of each line. It appeared to be working correctly but now in the scenario where line A (532.87,787.79)(486.34,769.85) and line B (490.89,764.018)(478.98,783.129) it says they intersect at (770.136, 487.08) when the lines don't intersect at all.
Has anyone any idea what is incorrect in the below code?
double dy[2], dx[2], m[2], b[2];
double xint, yint, xi, yi;
WsqT_Location_Message *location_msg_ptr = OPC_NIL;
FIN (intersect (<args>));
dy[0] = y2 - y1;
dx[0] = x2 - x1;
dy[1] = y4 - y3;
dx[1] = x4 - x3;
m[0] = dy[0] / dx[0];
m[1] = dy[1] / dx[1];
b[0] = y1 - m[0] * x1;
b[1] = y3 - m[1] * x3;
if (m[0] != m[1])
{
//slopes not equal, compute intercept
xint = (b[0] - b[1]) / (m[1] - m[0]);
yint = m[1] * xint + b[1];
//is intercept in both line segments?
if ((xint <= max(x1, x2)) && (xint >= min(x1, x2)) &&
(yint <= max(y1, y2)) && (yint >= min(y1, y2)) &&
(xint <= max(x3, x4)) && (xint >= min(x3, x4)) &&
(yint <= max(y3, y4)) && (yint >= min(y3, y4)))
{
if (xi && yi)
{
xi = xint;
yi = yint;
location_msg_ptr = (WsqT_Location_Message*)op_prg_mem_alloc(sizeof(WsqT_Location_Message));
location_msg_ptr->current_latitude = xi;
location_msg_ptr->current_longitude = yi;
}
FRET(location_msg_ptr);
}
}
FRET(location_msg_ptr);
}
There is an absolutely great and simple theory about lines and their intersections that is based on adding an extra dimensions to your points and lines. In this theory a line can be created from two points with one line of code and the point of line intersection can be calculated with one line of code. Moreover, points at the Infinity and lines at the Infinity can be represented with real numbers.
You probably heard about homogeneous representation when a point [x, y] is represented as [x, y, 1] and the line ax+by+c=0 is represented as [a, b, c]?
The transitioning to Cartesian coordinates for a general homogeneous representation of a point [x, y, w] is [x/w, y/w]. This little trick makes all the difference including representation of lines at infinity (e.g. [1, 0, 0]) and making line representation look similar to point one. This introduces a GREAT symmetry into formulas for numerous line/point manipulation and is an
absolute MUST to use in programming. For example,
It is very easy to find line intersections through vector product
p = l1xl2
A line can be created from two points is a similar way:
l=p1xp2
In the code of OpenCV it it just:
line = p1.cross(p2);
p = line1.cross(line2);
Note that there are no marginal cases (such as division by zero or parallel lines) to be concerned with here. My point is, I suggest to rewrite your code to take advantage of this elegant theory about lines and points.
Finally, if you don't use openCV, you can use a 3D point class and create your own cross product function similar to this one:
template<typename _Tp> inline Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const
{
return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x);
}
I've got two points between which im drawing a line (x1,y1 and x2,y2) but i need to know the coordinates of x3,y3 which is gapSize away from point x2,y2. Any ideas on how to solve this problem (the program is written in objective-c if that is helpful at all)?
You can simply calculate the angle in radians as
double rads = atan2(y2 - y1, x2 - x1);
Then you get the coordinates as follows:
double x3 = x2 + gapSize * cos(rads);
double y3 = y2 + gapSize * sin(rads);
Is this what you meant?
Compute the distance between P1 and P2: d=sqrt( (y2-y1)^2 + (x2-x1)^2)
Then x2 = (d*x1 + gapSize*x3) / (d+gapSize)
So x3 = (x2 * (d+gapSize) - d*x1) / gapSize
Similarly, y3 = (y2 * (d+gapSize) - d*y1) / gapSize
Sorry for the math. I didn't try to code it but it sounds right. I hope this helps.
There are many ways to do this. Simplest (to me) is the following. I'll write it in terms of mathematics since I can't even spell C.
Thus, we wish to find the point C = {x3,y3}, given points A = {x1,y1} and B = {x2,y2}.
The distance between the points is
d = ||B-A|| = sqrt((x2-x1)^2 + (y2-y1)^2)
A unit vector that points along the line is given by
V = (B - A)/d = {(x2 - x1)/d, (y2-y1)/d}
A new point that lies a distance of gapSize away from B, in the direction of that unit vector is
C = B + V*gapSize = {x2 + gapSize*(x2 - x1)/d, y2 + gapSize*(y2 - y1)/d}
I'm trying to generate a random Gaussian double in Objective-C (the same as random.nextGaussian in Java). However rand_gauss() doesn't seem to work. Anyone know a way of achieving this?
This link shows how to calculate it using the standard random() function.
I should note that you'll likely have to make the ranf() routine that converts the output of random() from [0,MAX_INT] to be from [0,1], but that shouldn't be too difficult.
From the linked article:
The polar form of the Box-Muller transformation is both faster and more robust numerically. The algorithmic description of it is:
float x1, x2, w, y1, y2;
do {
x1 = 2.0 * ranf() - 1.0;
x2 = 2.0 * ranf() - 1.0;
w = x1 * x1 + x2 * x2;
} while ( w >= 1.0 );
w = sqrt( (-2.0 * ln( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
Given vertices V1 (x1,y1,z1), V2 (x2,y2,z2), V3 (x3,y3,z3) of a triangle T, I have to find z coordinate of a point by it's x,y coordinate if I know that (x,y) lies within projection of triangle Tp (x1,y1), (x2,y2), (x3,y3).
Actually, triangle plane in 3D is defined by equation: Ax+By+Cz+D=0, and I can find z = (D-Ax-By)/C
The problem is that A, B, C, D are too expensive to calculate in run-time:
A = y1(z2-z3) + y2(z3-z1) + y3(z1-z2)
B = z1(x2-x3) + z2(x3-x1) + z3(x1-x2)
C = x1(y2-y3) + x2(y3-y1) + x3(y1-y2)
D = -x1(y2*z3 – y3*z2) – x2(y3*z1 – y1*z3) – x3 (y1*z2 – y2*z1)
Is it possible to calculate A, B, C, D using, say, opengl shaders? Are there optimized algorithms to find plane coefficients?
The technique is called Barycentric coordinates but the wiki page is pretty hard to follow -
See http://www.alecjacobson.com/weblog/?p=1596
float calcY(vec3 p1, vec3 p2, vec3 p3, float x, float z) {
float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
float l1 = ((p2.z - p3.z) * (x - p3.x) + (p3.x - p2.x) * (z - p3.z)) / det;
float l2 = ((p3.z - p1.z) * (x - p3.x) + (p1.x - p3.x) * (z - p3.z)) / det;
float l3 = 1.0f - l1 - l2;
return l1 * p1.y + l2 * p2.y + l3 * p3.y;
}
Code from http://www.gamedev.net/topic/597393-getting-the-height-of-a-point-on-a-triangle/ - carefull about computer graphics vs maths use of Y Z
ps. I Don't know of any faster version using shaders. One quick dirty+solution is to render the triangle using colors based on the height of the vertices and pick the pixel color at your X,Y - in practice this never ends up being much faster on a desktop machine, don't know about opengl-es