I just want to know how a line is drawn between two points. What is I need
is how the intermediate pixels are choosen while drawing a line. Given two poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any help is appreciated. Thanks in advance. Dilip Kumar Baluguri CWID: 50044123 Graduate Student- Computer Science TAMU-Commerce (630)383-9112 Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> - "If God had wanted man to play soccer, he wouldn't have given us arms." |
Dilip,
Here is my understanding. I'm sure it will be corrected if necessary. Suppose you want to draw a line from (x1,y2) to (x2,y2). First determine which is larger, deltaX = |x2-x1| or deltaY = |y2 - y1|. If deltaX is larger, then our line is going to have deltaX+1 pixels, with x running from x1 to x2. For each x value on the line (segment), the corresponding value of y is computed by interpolating: y = (int)( y1(x2 - x)/(x2 - x1) + y2(x - x1)/(x2 - x1) + 0.5) If deltaY is larger, then y runs from y1 to y2, and each x is computed to by a formula analogous to the above with x and y interchanged. If deltaX = deltaY, then do it either way. If the largest delta is 0, then just draw one pixel. In ImageJ programming, you should not have to do this computation if all you want to do is draw a line. There are ImageJ and AWT methods to handle it. Bob On Dec 27, 2009, at 8:16 PM, Dilip Baluguri wrote: > I just want to know how a line is drawn between two points. What is I need > is how the intermediate pixels are choosen while drawing a line. Given two > poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any help is > appreciated. > Thanks in advance. > > > > Dilip Kumar Baluguri > CWID: 50044123 > Graduate Student- Computer Science > TAMU-Commerce > (630)383-9112 > > Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> - > "If God had wanted man to play soccer, he wouldn't have given us arms." Robert Dougherty, Ph.D. President, OptiNav, Inc. 4176 148th Ave. NE Redmond, WA 98052 (425)891-4883 FAX (425)467-1119 www.optinav.com [hidden email] |
Hi Dilip,
Rob is right on the basic idea, however, in many cases, an integer-only method is used for efficiency which does not require any interpolation and hence floating point calculations. (I did not yet check what ImageJ does when creating ROIs) Look up "Bresenham algorithm" and "line drawing algorithm" Cheers Robert Dougherty <[hidden email]> Gesendet von: An ImageJ Interest [hidden email] Group Kopie <[hidden email]. GOV> Thema Re: Nelp needed 28.12.2009 05:55 Bitte antworten an ImageJ Interest Group <[hidden email]. GOV> Dilip, Here is my understanding. I'm sure it will be corrected if necessary. Suppose you want to draw a line from (x1,y2) to (x2,y2). First determine which is larger, deltaX = |x2-x1| or deltaY = |y2 - y1|. If deltaX is larger, then our line is going to have deltaX+1 pixels, with x running from x1 to x2. For each x value on the line (segment), the corresponding value of y is computed by interpolating: y = (int)( y1(x2 - x)/(x2 - x1) + y2(x - x1)/(x2 - x1) + 0.5) If deltaY is larger, then y runs from y1 to y2, and each x is computed to by a formula analogous to the above with x and y interchanged. If deltaX = deltaY, then do it either way. If the largest delta is 0, then just draw one pixel. In ImageJ programming, you should not have to do this computation if all you want to do is draw a line. There are ImageJ and AWT methods to handle it. Bob On Dec 27, 2009, at 8:16 PM, Dilip Baluguri wrote: > I just want to know how a line is drawn between two points. What is I need > is how the intermediate pixels are choosen while drawing a line. Given two > poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any help is > appreciated. > Thanks in advance. > > > > Dilip Kumar Baluguri > CWID: 50044123 > Graduate Student- Computer Science > TAMU-Commerce > (630)383-9112 > > Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> > "If God had wanted man to play soccer, he wouldn't have given us arms." Robert Dougherty, Ph.D. President, OptiNav, Inc. 4176 148th Ave. NE Redmond, WA 98052 (425)891-4883 FAX (425)467-1119 www.optinav.com [hidden email] ______________________________________________________________________ This email has been scanned by the MessageLabs Email Security System. For more information please visit http://www.messagelabs.com/email ______________________________________________________________________ |
In reply to this post by Dilip Baluguri
On Dec 27, 2009, at 9:16 PM, Dilip Baluguri <[hidden email]
> wrote: > I just want to know how a line is drawn between two points. What is > I need > is how the intermediate pixels are choosen while drawing a line. > Given two > poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any > help is > appreciated. > Thanks in advance. > I'm not sure how ImageJ draws lines, but most often this sort of problem is handled with an "Incremental Sum Algorithm". You can google for incremental sum algorithm and lines to find information about this technique. HTH, Phil |
In reply to this post by Robert Dougherty
Hi Bob,
as I understand it, in effect, the algorithm is the same as you describe (apart from a problem, see below), but it is implemented in a slightly different way. See the lineTo method in ImageProcessor.java (current version at http://rsb.info.nih.gov/ij/source/ij/process/ImageProcessor.java) First, the increments in x and y are calculated. They are proportional to the vector components from the starting point to the end point. The proportionality factor is chosen such that the increment with the larger absolute value has an absolute value of 1. Then, starting from the first pixel, the increment in x and y is added, and the pixel is set at the rounded value. Two specialties: - Lines with a length of more than 1 million pixels in x or y are considered erroneous (no image is that big) and ignored. - It seems that there is a bug with negative starting values. Here is an example macro: newImage("test", "8-bit White", 100, 100, 1); drawLine(1, -1, 9, 1); drawLine(1, 1, 9, 3); drawLine(1, 3, 9, 5); The first (uppermost) line is not parallel to the two first one although it should be. I think that the reason for the bug is in macro/Functions.java (adding 0.5 instead of Math.round), but I also do not understand the code in lineTo in this respect (is the case distinction for positive/negative cx, cy when calculating the starting point x, y supposed to compensate for the macro/Functions.java problem?) Michael __________________________________________________________________ On Mon, December 28, 2009 05:55, Robert Dougherty wrote: > Dilip, > > Here is my understanding. I'm sure it will be corrected if necessary. > Suppose you want to draw a line from (x1,y2) to (x2,y2). First > determine which is larger, deltaX = |x2-x1| or deltaY = |y2 - y1|. If > deltaX is larger, then our line is going to have deltaX+1 pixels, with x > running from x1 to x2. For each x value on the line (segment), the > corresponding value of y is computed by interpolating: > > y = (int)( y1(x2 - x)/(x2 - x1) + y2(x - x1)/(x2 - x1) + 0.5) > > If deltaY is larger, then y runs from y1 to y2, and each x is computed to > by a formula analogous to the above with x and y interchanged. If deltaX > = deltaY, then do it either way. If the largest delta is 0, then just > draw one pixel. > > In ImageJ programming, you should not have to do this computation if all > you want to do is draw a line. There are ImageJ and AWT methods to handle > it. > > Bob > > On Dec 27, 2009, at 8:16 PM, Dilip Baluguri wrote: > >> I just want to know how a line is drawn between two points. What is I >> need >> is how the intermediate pixels are choosen while drawing a line. Given >> two >> poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any >> help is >> appreciated. >> Thanks in advance. >> >> >> >> Dilip Kumar Baluguri >> CWID: 50044123 >> Graduate Student- Computer Science >> TAMU-Commerce >> (630)383-9112 >> >> Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> >> - >> "If God had wanted man to play soccer, he wouldn't have given us arms." > > Robert Dougherty, Ph.D. > President, OptiNav, Inc. > 4176 148th Ave. NE > Redmond, WA 98052 > (425)891-4883 > FAX (425)467-1119 > www.optinav.com > [hidden email] > |
The negative starting value line drawing bugs are fixed in the 1.43n daily build. The ij.process.ImageProcessor.lineTo() method and the methods in the ij.macro.Functions that call it now use Math.round() instead of adding 0.5. Here is what the lineTo() method now looks like:
/** Draws a line from the current drawing location (cx,cy) to (x2,y2). */ public void lineTo(int x2, int y2) { int dx = x2-cx; int dy = y2-cy; int absdx = dx>=0?dx:-dx; int absdy = dy>=0?dy:-dy; int n = absdy>absdx?absdy:absdx; double xinc = (double)dx/n; double yinc = (double)dy/n; double x = cx; double y = cy; n++; cx = x2; cy = y2; if (n>1000000) return; do { if (lineWidth==1) drawPixel((int)Math.round(x), (int)Math.round(y)); else if (lineWidth==2) drawDot2((int)Math.round(x), (int)Math.round(y)); else drawDot((int)x, (int)y); x += xinc; y += yinc; } while (--n>0); //if (lineWidth>2) resetRoi(); } -wayne On Dec 28, 2009, at 9:10 AM, Michael Schmid wrote: > Hi Bob, > > as I understand it, in effect, the algorithm is the same as you describe > (apart from a problem, see below), but it is implemented in a slightly > different way. See the lineTo method in ImageProcessor.java (current > version at > http://rsb.info.nih.gov/ij/source/ij/process/ImageProcessor.java) > > First, the increments in x and y are calculated. They are proportional to > the vector components from the starting point to the end point. The > proportionality factor is chosen such that the increment with the larger > absolute value has an absolute value of 1. Then, starting from the first > pixel, the increment in x and y is added, and the pixel is set at the > rounded value. > > Two specialties: > - Lines with a length of more than 1 million pixels in x or y are > considered erroneous (no image is that big) and ignored. > > - It seems that there is a bug with negative starting values. Here is an > example macro: > newImage("test", "8-bit White", 100, 100, 1); > drawLine(1, -1, 9, 1); > drawLine(1, 1, 9, 3); > drawLine(1, 3, 9, 5); > The first (uppermost) line is not parallel to the two first one although > it should be. > > I think that the reason for the bug is in macro/Functions.java (adding 0.5 > instead of Math.round), but I also do not understand the code in lineTo in > this respect (is the case distinction for positive/negative cx, cy when > calculating the starting point x, y supposed to compensate for the > macro/Functions.java problem?) > > > Michael > __________________________________________________________________ > > On Mon, December 28, 2009 05:55, Robert Dougherty wrote: >> Dilip, >> >> Here is my understanding. I'm sure it will be corrected if necessary. >> Suppose you want to draw a line from (x1,y2) to (x2,y2). First >> determine which is larger, deltaX = |x2-x1| or deltaY = |y2 - y1|. If >> deltaX is larger, then our line is going to have deltaX+1 pixels, with x >> running from x1 to x2. For each x value on the line (segment), the >> corresponding value of y is computed by interpolating: >> >> y = (int)( y1(x2 - x)/(x2 - x1) + y2(x - x1)/(x2 - x1) + 0.5) >> >> If deltaY is larger, then y runs from y1 to y2, and each x is computed to >> by a formula analogous to the above with x and y interchanged. If deltaX >> = deltaY, then do it either way. If the largest delta is 0, then just >> draw one pixel. >> >> In ImageJ programming, you should not have to do this computation if all >> you want to do is draw a line. There are ImageJ and AWT methods to handle >> it. >> >> Bob >> >> On Dec 27, 2009, at 8:16 PM, Dilip Baluguri wrote: >> >>> I just want to know how a line is drawn between two points. What is I >>> need >>> is how the intermediate pixels are choosen while drawing a line. Given >>> two >>> poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any >>> help is >>> appreciated. >>> Thanks in advance. >>> >>> >>> >>> Dilip Kumar Baluguri >>> CWID: 50044123 >>> Graduate Student- Computer Science >>> TAMU-Commerce >>> (630)383-9112 >>> >>> Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> >>> - >>> "If God had wanted man to play soccer, he wouldn't have given us arms." >> >> Robert Dougherty, Ph.D. >> President, OptiNav, Inc. >> 4176 148th Ave. NE >> Redmond, WA 98052 >> (425)891-4883 >> FAX (425)467-1119 >> www.optinav.com >> [hidden email] >> |
Wayne,
Having watched this list for years, and dreamed of the day that I could make a contribution or even ask a coherent question. Since that day has not occurred, I am left with the following. At least on my own behalf, and hopefully on behalf of all of us non-contributing beneficiaries of the excellent efforts of the ImageJ "Coder-In-Chief" and all those who do contribute plugin code. May the gods of code and all the other Gods of good will give you well-deserved comfort and contentment from your labors on this great work. Thank you for your dogged and conscientious attention to the smallest requests for help in understanding how your creation works and, in addition, your willingness to modify it when the change makes sense. You and the others mentioned have taken responsibility for an effort that benefits a world-wide population of scientific and other users of imaging. This achievement is NOT a small potato! Your record of positive achievement and contribution gives me the right to tell you that you are, by your actions, not your words, a man and persons who are eminently worthy of my trust and confidence. Finally, for all of you who are employees of Federal and/or State entities, I hope we are compensating you accordingly (though, in fact, I have never seen it to be so). Thus, I am left with the power to offer you thanks and continued gratitude for all that you have done for us all and that which I know you will continue to provide as long as you are able. Happy New Year, whenever it comes, and God bless, whoever S/He is, Frederick C. Monson a very grateful, and impressed, user ________________________________________ From: ImageJ Interest Group [[hidden email]] On Behalf Of Wayne Rasband [[hidden email]] Sent: Monday, December 28, 2009 10:22 AM To: [hidden email] Subject: Re: Nelp needed The negative starting value line drawing bugs are fixed in the 1.43n daily build. The ij.process.ImageProcessor.lineTo() method and the methods in the ij.macro.Functions that call it now use Math.round() instead of adding 0.5. Here is what the lineTo() method now looks like: /** Draws a line from the current drawing location (cx,cy) to (x2,y2). */ public void lineTo(int x2, int y2) { int dx = x2-cx; int dy = y2-cy; int absdx = dx>=0?dx:-dx; int absdy = dy>=0?dy:-dy; int n = absdy>absdx?absdy:absdx; double xinc = (double)dx/n; double yinc = (double)dy/n; double x = cx; double y = cy; n++; cx = x2; cy = y2; if (n>1000000) return; do { if (lineWidth==1) drawPixel((int)Math.round(x), (int)Math.round(y)); else if (lineWidth==2) drawDot2((int)Math.round(x), (int)Math.round(y)); else drawDot((int)x, (int)y); x += xinc; y += yinc; } while (--n>0); //if (lineWidth>2) resetRoi(); } -wayne On Dec 28, 2009, at 9:10 AM, Michael Schmid wrote: > Hi Bob, > > as I understand it, in effect, the algorithm is the same as you describe > (apart from a problem, see below), but it is implemented in a slightly > different way. See the lineTo method in ImageProcessor.java (current > version at > http://rsb.info.nih.gov/ij/source/ij/process/ImageProcessor.java) > > First, the increments in x and y are calculated. They are proportional to > the vector components from the starting point to the end point. The > proportionality factor is chosen such that the increment with the larger > absolute value has an absolute value of 1. Then, starting from the first > pixel, the increment in x and y is added, and the pixel is set at the > rounded value. > > Two specialties: > - Lines with a length of more than 1 million pixels in x or y are > considered erroneous (no image is that big) and ignored. > > - It seems that there is a bug with negative starting values. Here is an > example macro: > newImage("test", "8-bit White", 100, 100, 1); > drawLine(1, -1, 9, 1); > drawLine(1, 1, 9, 3); > drawLine(1, 3, 9, 5); > The first (uppermost) line is not parallel to the two first one although > it should be. > > I think that the reason for the bug is in macro/Functions.java (adding 0.5 > instead of Math.round), but I also do not understand the code in lineTo in > this respect (is the case distinction for positive/negative cx, cy when > calculating the starting point x, y supposed to compensate for the > macro/Functions.java problem?) > > > Michael > __________________________________________________________________ > > On Mon, December 28, 2009 05:55, Robert Dougherty wrote: >> Dilip, >> >> Here is my understanding. I'm sure it will be corrected if necessary. >> Suppose you want to draw a line from (x1,y2) to (x2,y2). First >> determine which is larger, deltaX = |x2-x1| or deltaY = |y2 - y1|. If >> deltaX is larger, then our line is going to have deltaX+1 pixels, with x >> running from x1 to x2. For each x value on the line (segment), the >> corresponding value of y is computed by interpolating: >> >> y = (int)( y1(x2 - x)/(x2 - x1) + y2(x - x1)/(x2 - x1) + 0.5) >> >> If deltaY is larger, then y runs from y1 to y2, and each x is computed to >> by a formula analogous to the above with x and y interchanged. If deltaX >> = deltaY, then do it either way. If the largest delta is 0, then just >> draw one pixel. >> >> In ImageJ programming, you should not have to do this computation if all >> you want to do is draw a line. There are ImageJ and AWT methods to handle >> it. >> >> Bob >> >> On Dec 27, 2009, at 8:16 PM, Dilip Baluguri wrote: >> >>> I just want to know how a line is drawn between two points. What is I >>> need >>> is how the intermediate pixels are choosen while drawing a line. Given >>> two >>> poins A(10,20) and B(40,200) how intermediate pixels are choosen.Any >>> help is >>> appreciated. >>> Thanks in advance. >>> >>> >>> >>> Dilip Kumar Baluguri >>> CWID: 50044123 >>> Graduate Student- Computer Science >>> TAMU-Commerce >>> (630)383-9112 >>> >>> Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> >>> - >>> "If God had wanted man to play soccer, he wouldn't have given us arms." >> >> Robert Dougherty, Ph.D. >> President, OptiNav, Inc. >> 4176 148th Ave. NE >> Redmond, WA 98052 >> (425)891-4883 >> FAX (425)467-1119 >> www.optinav.com >> [hidden email] >> |
Free forum by Nabble | Edit this page |