2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
108
Task/Xiaolin-Wus-line-algorithm/C/xiaolin-wus-line-algorithm-3.c
Normal file
108
Task/Xiaolin-Wus-line-algorithm/C/xiaolin-wus-line-algorithm-3.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
public class Line
|
||||
{
|
||||
private double x0, y0, x1, y1;
|
||||
private Color foreColor;
|
||||
private byte lineStyleMask;
|
||||
private int thickness;
|
||||
private float globalm;
|
||||
|
||||
public Line(double x0, double y0, double x1, double y1, Color color, byte lineStyleMask, int thickness)
|
||||
{
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.y1 = y1;
|
||||
this.x1 = x1;
|
||||
|
||||
this.foreColor = color;
|
||||
|
||||
this.lineStyleMask = lineStyleMask;
|
||||
|
||||
this.thickness = thickness;
|
||||
|
||||
}
|
||||
|
||||
private void plot(Bitmap bitmap, double x, double y, double c)
|
||||
{
|
||||
int alpha = (int)(c * 255);
|
||||
if (alpha > 255) alpha = 255;
|
||||
if (alpha < 0) alpha = 0;
|
||||
Color color = Color.FromArgb(alpha, foreColor);
|
||||
if (BitmapDrawHelper.checkIfInside((int)x, (int)y, bitmap))
|
||||
{
|
||||
bitmap.SetPixel((int)x, (int)y, color);
|
||||
}
|
||||
}
|
||||
|
||||
int ipart(double x) { return (int)x;}
|
||||
|
||||
int round(double x) {return ipart(x+0.5);}
|
||||
|
||||
double fpart(double x) {
|
||||
if(x<0) return (1-(x-Math.Floor(x)));
|
||||
return (x-Math.Floor(x));
|
||||
}
|
||||
|
||||
double rfpart(double x) {
|
||||
return 1-fpart(x);
|
||||
}
|
||||
|
||||
|
||||
public void draw(Bitmap bitmap) {
|
||||
bool steep = Math.Abs(y1-y0)>Math.Abs(x1-x0);
|
||||
double temp;
|
||||
if(steep){
|
||||
temp=x0; x0=y0; y0=temp;
|
||||
temp=x1;x1=y1;y1=temp;
|
||||
}
|
||||
if(x0>x1){
|
||||
temp = x0;x0=x1;x1=temp;
|
||||
temp = y0;y0=y1;y1=temp;
|
||||
}
|
||||
|
||||
double dx = x1-x0;
|
||||
double dy = y1-y0;
|
||||
double gradient = dy/dx;
|
||||
|
||||
double xEnd = round(x0);
|
||||
double yEnd = y0+gradient*(xEnd-x0);
|
||||
double xGap = rfpart(x0+0.5);
|
||||
double xPixel1 = xEnd;
|
||||
double yPixel1 = ipart(yEnd);
|
||||
|
||||
if(steep){
|
||||
plot(bitmap, yPixel1, xPixel1, rfpart(yEnd)*xGap);
|
||||
plot(bitmap, yPixel1+1, xPixel1, fpart(yEnd)*xGap);
|
||||
}else{
|
||||
plot(bitmap, xPixel1,yPixel1, rfpart(yEnd)*xGap);
|
||||
plot(bitmap, xPixel1, yPixel1+1, fpart(yEnd)*xGap);
|
||||
}
|
||||
double intery = yEnd+gradient;
|
||||
|
||||
xEnd = round(x1);
|
||||
yEnd = y1+gradient*(xEnd-x1);
|
||||
xGap = fpart(x1+0.5);
|
||||
double xPixel2 = xEnd;
|
||||
double yPixel2 = ipart(yEnd);
|
||||
if(steep){
|
||||
plot(bitmap, yPixel2, xPixel2, rfpart(yEnd)*xGap);
|
||||
plot(bitmap, yPixel2+1, xPixel2, fpart(yEnd)*xGap);
|
||||
}else{
|
||||
plot(bitmap, xPixel2, yPixel2, rfpart(yEnd)*xGap);
|
||||
plot(bitmap, xPixel2, yPixel2+1, fpart(yEnd)*xGap);
|
||||
}
|
||||
|
||||
if(steep){
|
||||
for(int x=(int)(xPixel1+1);x<=xPixel2-1;x++){
|
||||
plot(bitmap, ipart(intery), x, rfpart(intery));
|
||||
plot(bitmap, ipart(intery)+1, x, fpart(intery));
|
||||
intery+=gradient;
|
||||
}
|
||||
}else{
|
||||
for(int x=(int)(xPixel1+1);x<=xPixel2-1;x++){
|
||||
plot(bitmap, x,ipart(intery), rfpart(intery));
|
||||
plot(bitmap, x, ipart(intery)+1, fpart(intery));
|
||||
intery+=gradient;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
import java.awt.*;
|
||||
import static java.lang.Math.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class XiaolinWu extends JPanel {
|
||||
|
||||
public XiaolinWu() {
|
||||
Dimension dim = new Dimension(640, 640);
|
||||
setPreferredSize(dim);
|
||||
setBackground(Color.white);
|
||||
}
|
||||
|
||||
void plot(Graphics2D g, double x, double y, double c) {
|
||||
g.setColor(new Color(0f, 0f, 0f, (float)c));
|
||||
g.fillOval((int) x, (int) y, 2, 2);
|
||||
}
|
||||
|
||||
int ipart(double x) {
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
double fpart(double x) {
|
||||
return x - floor(x);
|
||||
}
|
||||
|
||||
double rfpart(double x) {
|
||||
return 1.0 - fpart(x);
|
||||
}
|
||||
|
||||
void drawLine(Graphics2D g, double x0, double y0, double x1, double y1) {
|
||||
|
||||
boolean steep = abs(y1 - y0) > abs(x1 - x0);
|
||||
if (steep)
|
||||
drawLine(g, y0, x0, y1, x1);
|
||||
|
||||
if (x0 > x1)
|
||||
drawLine(g, x1, y1, x0, y0);
|
||||
|
||||
double dx = x1 - x0;
|
||||
double dy = y1 - y0;
|
||||
double gradient = dy / dx;
|
||||
|
||||
// handle first endpoint
|
||||
double xend = round(x0);
|
||||
double yend = y0 + gradient * (xend - x0);
|
||||
double xgap = rfpart(x0 + 0.5);
|
||||
double xpxl1 = xend; // this will be used in the main loop
|
||||
double ypxl1 = ipart(yend);
|
||||
|
||||
if (steep) {
|
||||
plot(g, ypxl1, xpxl1, rfpart(yend) * xgap);
|
||||
plot(g, ypxl1 + 1, xpxl1, fpart(yend) * xgap);
|
||||
} else {
|
||||
plot(g, xpxl1, ypxl1, rfpart(yend) * xgap);
|
||||
plot(g, xpxl1, ypxl1 + 1, fpart(yend) * xgap);
|
||||
}
|
||||
|
||||
// first y-intersection for the main loop
|
||||
double intery = yend + gradient;
|
||||
|
||||
// handle second endpoint
|
||||
xend = round(x1);
|
||||
yend = y1 + gradient * (xend - x1);
|
||||
xgap = fpart(x1 + 0.5);
|
||||
double xpxl2 = xend; // this will be used in the main loop
|
||||
double ypxl2 = ipart(yend);
|
||||
|
||||
if (steep) {
|
||||
plot(g, ypxl2, xpxl2, rfpart(yend) * xgap);
|
||||
plot(g, ypxl2 + 1, xpxl2, fpart(yend) * xgap);
|
||||
} else {
|
||||
plot(g, xpxl2, ypxl2, rfpart(yend) * xgap);
|
||||
plot(g, xpxl2, ypxl2 + 1, fpart(yend) * xgap);
|
||||
}
|
||||
|
||||
// main loop
|
||||
for (double x = xpxl1 + 1; x <= xpxl2 - 1; x++) {
|
||||
if (steep) {
|
||||
plot(g, ipart(intery), x, rfpart(intery));
|
||||
plot(g, ipart(intery) + 1, x, fpart(intery));
|
||||
} else {
|
||||
plot(g, x, ipart(intery), rfpart(intery));
|
||||
plot(g, x, ipart(intery) + 1, fpart(intery));
|
||||
}
|
||||
intery = intery + gradient;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics gg) {
|
||||
super.paintComponent(gg);
|
||||
Graphics2D g = (Graphics2D) gg;
|
||||
|
||||
drawLine(g, 550, 170, 50, 435);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFrame f = new JFrame();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setTitle("Xiaolin Wu's line algorithm");
|
||||
f.setResizable(false);
|
||||
f.add(new XiaolinWu(), BorderLayout.CENTER);
|
||||
f.pack();
|
||||
f.setLocationRelativeTo(null);
|
||||
f.setVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,82 +1,63 @@
|
|||
/*REXX program plots/draws a line using the Xiaolin Wu line algorithm.*/
|
||||
background = 'fa'x /*background char: middle-dot. */
|
||||
image. = background /*fill the array with middle-dots*/
|
||||
plotC = '░▒▓█' /*chars used for plotting points.*/
|
||||
EoE = 1000 /*EOE = End Of Earth, er... plot.*/
|
||||
do j=-EoE to +EoE /*draw grid from lowest──►highest*/
|
||||
image.j.0 = '─' /*draw the horizontal axis. */
|
||||
image.0.j = '│' /* " " verical " */
|
||||
end /*j*/
|
||||
image.0.0 = '┼' /*"draw" the axis origin (char). */
|
||||
parse arg xi yi xf yf . /*allow specifying line-end pts. */
|
||||
if xi=='' | xi==',' then xi = 1 /*if not specified, use default. */
|
||||
if yi=='' | yi==',' then yi = 2 /* " " " " " */
|
||||
if xf=='' | xf==',' then xf = 11 /* " " " " " */
|
||||
if yf=='' | yf==',' then yf = 12 /* " " " " " */
|
||||
minX=0; minY=0 /*used as limits for plotting. */
|
||||
maxX=0; maxY=0 /* " " " " " */
|
||||
call line_draw xi, yi, xf, yf /*call subroutine and draw line. */
|
||||
border = 2 /*allow additional space for plot*/
|
||||
minX=minX-border*2; maxX=maxX+border*2
|
||||
minY=minY-border ; maxY=maxY+border
|
||||
do y=maxY by -1 to minY; _= /*build a row*/
|
||||
do x=minX to maxX
|
||||
_=_ || image.x.y
|
||||
end /*x*/
|
||||
say _ /*display row*/
|
||||
end /*y*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*────────────────────────────────DRAW_LINE subroutine──────────────────*/
|
||||
line_draw: procedure expose background image. minX maxX minY maxY plotC
|
||||
parse arg x1, y1, x2, y2; switchXY=0; dx=x2-x1
|
||||
dy=y2-y1
|
||||
if abs(dx)<abs(dy) then do
|
||||
parse value x1 y1 with y1 x1 /*swap x1 & y1*/
|
||||
parse value x2 y2 with y2 x2 /*swap x2 & y2*/
|
||||
parse value dx dy with dy dx /*swap dx & dy*/
|
||||
end
|
||||
if x2<x1 then do
|
||||
parse value x1 x2 with x2 x1 /*swap x1 & x2*/
|
||||
parse value y1 y2 with y2 y1 /*swap y1 & y2*/
|
||||
switchXY=1
|
||||
end
|
||||
/*REXX program plots/draws a line using the Xiaolin Wu line algorithm. */
|
||||
background='·' /*background character: a middle-dot. */
|
||||
image.=background /*fill the array with middle-dots. */
|
||||
plotC='░▒▓█' /*characters used for plotting points. */
|
||||
EoE=1000 /*EOE = End Of Earth, er, ··· graph. */
|
||||
do j=-EoE to +EoE /*define the graph: lowest ──► highest.*/
|
||||
image.j.0='─' /*define the graph's horizontal axis. */
|
||||
image.0.j='│' /* " " " verical " */
|
||||
end /*j*/
|
||||
image.0.0='┼' /*define the graph's axis origin (char)*/
|
||||
parse arg xi yi xf yf . /*allow specifying the line-end points.*/
|
||||
if xi=='' | xi=="," then xi= 1 /*Not specified? Then use the default.*/
|
||||
if yi=='' | yi=="," then yi= 2 /* " " " " " " */
|
||||
if xf=='' | xf=="," then xf=11 /* " " " " " " */
|
||||
if yf=='' | yf=="," then yf=12 /* " " " " " " */
|
||||
minX=0; minY=0 /*use these as the limits for plotting.*/
|
||||
maxX=0; maxY=0 /* " " " " " " " */
|
||||
call drawLine xi, yi, xf, yf /*invoke subroutine and graph the line.*/
|
||||
border=2 /*allow additional space (plot border).*/
|
||||
minX=minX-border*2; maxX=maxX+border*2 /* *2 preserves screen's aspect ratio.*/
|
||||
minY=minY-border ; maxY=maxY+border
|
||||
do y=maxY by -1 to minY; _= /*build a row.*/
|
||||
do x=minX to maxX; _=_ || image.x.y; end /*x*/
|
||||
say _ /*display row.*/
|
||||
end /*y*/ /*graph is cropped by the MINs and MAXs*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
drawLine: parse arg x1,y1,x2,y2; switchXY=0; dx=x2-x1
|
||||
dy=y2-y1
|
||||
if abs(dx) < abs(dy) then parse value x1 y1 x2 y2 dx dy with,
|
||||
y1 x2 y2 x2 dy dx
|
||||
if x2<x1 then parse value x1 x2 y1 y2 1 with,
|
||||
x2 x1 y2 y1 switchXY
|
||||
gradient=dy/dx
|
||||
xend=round(x1) /*◄─────────────────1st endpoint.══════════════*/
|
||||
yend=y1 + gradient*(xend-x1); xgap=1-fpart(x1 + .5)
|
||||
xpx11=xend; ypx11=floor(yend)
|
||||
intery=yend+gradient
|
||||
call plotXY xpx11, ypx11, brite(1-fpart(yend*xgap)), switchXY
|
||||
call plotXY xpx11, ypx11+1, brite( fpart(yend*xgap)), switchXY
|
||||
xend=round(x2) /*◄─────────────────2nd endpoint.══════════════*/
|
||||
yend=y2 + gradient*(xend-x2); xgap=fpart(x2 + .5)
|
||||
xpx12=xend; ypx12=floor(yend)
|
||||
call plotXY xpx12, ypx12 , brite(1-fpart(yend*xgap)), switchXY
|
||||
call plotXY xpx12, ypx12+1, brite( fpart(yend*xgap)), switchXY
|
||||
|
||||
gradient = dy/dx
|
||||
xend = round(x1) /*────1st endpoint────────────────────*/
|
||||
yend = y1 + gradient * (xend-x1)
|
||||
intery = yend + gradient
|
||||
xgap = 1 - fpart(x1+.5)
|
||||
xpx11 = xend; ypx11 = floor(yend); ypx11_=ypx11+1
|
||||
call plotXY xpx11, ypx11, brite(1-fpart(yend*xgap)),switchXY
|
||||
call plotXY xpx11, ypx11_, brite( fpart(yend*xgap)),switchXY
|
||||
do x=xpx11+1 to xpx12-1 /*◄───draw the line.═════════════*/
|
||||
!intery=floor(intery)
|
||||
call plotXY x, !intery , brite(1-fpart(intery)), switchXY
|
||||
call plotXY x, !intery+1, brite( fpart(intery)), switchXY
|
||||
intery=intery+gradient
|
||||
end /*x*/
|
||||
return
|
||||
/*────────────────────────────────short subroutines and functions.────────────*/
|
||||
brite: return substr(background||plotC, 1+round(abs(arg(1))*length(plotC)),1)
|
||||
floor: parse arg ?; _=trunc(?); return _ - (?<0) * (?\=_)
|
||||
fpart: parse arg ?; return abs(? - trunc(?))
|
||||
round: return format(arg(1), , word(arg(2) 0, 1))
|
||||
|
||||
xend = round(x2) /*────2nd endpoint────────────────────*/
|
||||
yend = y2 + gradient * (xend-x2)
|
||||
xgap = fpart(x2+.5)
|
||||
xpx12 = xend; ypx12 = floor(yend); ypx12_=ypx12+1
|
||||
call plotXY xpx12, ypx12, brite(1-fpart(yend*xgap)), switchXY
|
||||
call plotXY xpx12, ypx12_, brite( fpart(yend*xgap)), switchXY
|
||||
|
||||
do x=xpx11+1 to xpx12-1 /*────draw the line───────────────────*/
|
||||
!intery = floor(intery)
|
||||
!intery_ = !intery+1
|
||||
call plotXY x, !intery, brite(1-fpart(intery)), switchXY
|
||||
call plotXY x, !intery_, brite( fpart(intery)), switchXY
|
||||
intery = intery + gradient
|
||||
end /*x*/
|
||||
return
|
||||
/*────────────────────────────────BRITE subroutine──────────────────────*/
|
||||
brite: procedure expose background plotC; parse arg p
|
||||
return substr(background || plotC, 1+round(abs(p)*length(plotC)), 1)
|
||||
/*────────────────────────────────PLOTXY subroutine─────────────────────*/
|
||||
plotXY: procedure expose image. minX maxX minY maxY
|
||||
parse arg xx, yy, bc, switchYX; if switchYX then parse arg yy, xx
|
||||
image.xx.yy=bc; minX=min(minX,xx); maxX=max(maxX,xx)
|
||||
minY=min(minY,yy); maxY=max(maxY,yy)
|
||||
return
|
||||
/*────────────────────────────────FLOOR subroutine──────────────────────*/
|
||||
floor: procedure; parse arg ?; _=trunc(?); return _-(?<0)*(?\=_)
|
||||
/*────────────────────────────────FPART subroutine──────────────────────*/
|
||||
fpart: procedure; parse arg ?; return abs(?-trunc(?))
|
||||
/*────────────────────────────────ROUND subroutine─────────arg2 is place*/
|
||||
round: return format(arg(1), , word(arg(2) 0, 1))
|
||||
plotXY: parse arg xx,yy,bc,switchYX; if switchYX then parse arg yy,xx
|
||||
image.xx.yy=bc; minX=min(minX,xx); maxX=max(maxX,xx)
|
||||
minY=min(minY,yy); maxY=max(maxY,yy)
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue