Xiaolin Wu's line algorithm: Difference between revisions

m (syntax highlighting fixup automation)
Line 2,315:
img.drawLine(400, 700, x1.toFloat, 100)
img.savePNG("xiaoling_wu.png", compression = 9)</syntaxhighlight>
 
=={{header|ObjectIcon}}==
The program puts up a window. In the window you can draw a line by left-mouse-button-push for one endpoint, and then right-mouse-button-push for the other endpoint. You can draw multiple lines. When you leave (by pressing "q", for instance, or closing the window), the program stores the image as a PNG.
 
Rather than vary the color as such, I vary the opacity.
 
<syntaxhighlight lang="objecticon">
import
graphics,
ipl.graphics,
io
 
procedure main ()
local width, height
local done, w, event
local x1, y1, x2, y2
 
width := 640
height := 480
 
w := Window().
set_size(width, height).
set_bg("white").
set_canvas("normal") | stop(&why)
 
done := &no
while /done do
{
if *w.pending() ~= 0 then
{
event := w.event()
case event[1] of
{
QuitEvents() : done := &yes
Mouse.LEFT_PRESS:
{
x1 := event[2]; y1 := event[3]
}
Mouse.RIGHT_PRESS:
{
x2 := event[2]; y2 := event[3]
draw_line (w, x1, y1, x2, y2)
}
}
}
}
 
w.get_pixels().to_file("xiaolin_wu_line_algorithm_OI.png")
end
 
procedure draw_line (w, x0, y0, x1, y1)
local steep
local dx, dy, gradient
local xend, yend, xgap, intery
local xpxl1, ypxl1
local xpxl2, ypxl2
local x
 
x0 := real (x0)
y0 := real (y0)
x1 := real (x1)
y1 := real (y1)
 
# In Object Icon (as in Icon), comparisons DO NOT return boolean
# values! They either SUCCEED or they FAIL. Thus the need for an
# "if-then-else" here.
steep := if abs (y1 - y0) > abs (x1 - x0) then &yes else &no
 
if \steep then { x0 :=: y0; x1 :=: y1 }
if x0 > x1 then { x0 :=: x1; y0 :=: y1 }
dx := x1 - x0; dy := y1 - y0
gradient := if dx = 0 then 1.0 else dy / dx
 
# Handle the first endpoint.
xend := round (x0); yend := y0 + (gradient * (xend - x0))
xgap := rfpart (x0 + 0.5)
xpxl1 := xend; ypxl1 := ipart (yend)
if \steep then
{
plot (w, ypxl1, xpxl2, rfpart (yend) * xgap)
plot (w, ypxl1 + 1, xpxl1, fpart(yend) * xgap)
}
else
{
plot (w, xpxl1, ypxl1, rfpart (yend) * xgap)
plot (w, xpxl1, ypxl1 + 1, fpart (yend) * xgap)
}
 
# The first y-intersection.
intery := yend + gradient
 
# Handle the second endpoint.
xend := round (x1); yend := y1 + (gradient * (xend - x1))
xgap := fpart (x1 + 0.5)
xpxl2 := xend; ypxl2 := ipart (yend)
if \steep then
{
plot (w, ypxl2, xpxl2, rfpart (yend) * xgap)
plot (w, ypxl2 + 1, xpxl2, fpart (yend) * xgap)
}
else
{
plot (w, xpxl2, ypxl2, rfpart (yend) * xgap)
plot (w, xpxl2, ypxl2 + 1, fpart (yend) * xgap)
}
 
if \steep then
every x := xpxl1 + 1 to xpxl2 - 1 do
{
plot (w, ipart (intery), x, rfpart (intery))
plot (w, ipart (intery) + 1, x, fpart (intery))
intery := intery + gradient
}
else
every x := xpxl1 + 1 to xpxl2 - 1 do
{
plot(w, x, ipart (intery), rfpart (intery))
plot(w, x, ipart (intery) + 1, fpart (intery))
intery := intery + gradient
}
 
return
end
 
procedure plot (w, x, y, c)
w.set_fg ("black " || round (100.0 * c) || "%")
w.draw_point (x, y)
return
end
 
procedure ipart (x)
local i
i := integer (x)
return (if i = x then i else if x < 0 then i - 1 else i)
end
 
procedure round (x)
return ipart (x + 0.5)
end
 
procedure fpart (x)
return x - ipart (x)
end
 
procedure rfpart (x)
return 1.0 - fpart (x)
end
</syntaxhighlight>
 
{{out}}
An example:
[[File:Xiaolin wu line algorithm OI.2023.04.26.17.23.18.png|thumb|none|alt=Some straight lines, antialiased. Black on white.]]
 
=={{header|Pascal}}==
1,448

edits