Skip to content

Instantly share code, notes, and snippets.

@col000r
Created May 13, 2014 13:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save col000r/77439cbc31d007c4c314 to your computer and use it in GitHub Desktop.
Save col000r/77439cbc31d007c4c314 to your computer and use it in GitHub Desktop.
A translation of the code found on wikipedia to C# for use in the unity editor. (I used this to draw lines on a texture, then saved the texture as a PNG...)
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class DrawLineAATest : EditorWindow {
private Texture2D tex;
//http://en.wikipedia.org/wiki/Xiaolin_Wu's_line_algorithm
void Plot(float x, float y, float c, Color col) { // is plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
col.a = c;
tex.SetPixel(Mathf.RoundToInt(x), Mathf.RoundToInt(y), col);
}
void Plot(int x, int y, float c, Color col) { // is plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
col.a = c;
tex.SetPixel(x, y, col);
}
float IntegerPart(float x) { //is return 'integer part of x'
return Mathf.Round(x);
}
float Round(float x) { //is
return IntegerPart(x + 0.5f);
}
float FractionalPart(float x) { //is return 'fractional part of x'
return x - Mathf.RoundToInt(x);
}
float rFractionalPart(float x) { //is
return 1f - FractionalPart(x);
}
void DrawAALine(int x0, int y0, int x1, int y1, Color col) { //is
//TEMP TEST: draw point at beginning and end
Plot(x0, y0, 1f, col);
Plot(x1, y1, 1f, col);
bool steep = Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0);
if (steep) {
int t0 = x0;
x0 = y0;
y0 = t0;
int t1 = x1;
x1 = y1;
y1 = t1;
// swap(x0, y0);
// swap(x1, y1);
}
if (x0 > x1) {
int xT = x0;
x0 = x1;
x1 = xT;
int yT = y0;
y0 = y1;
y1 = yT;
// swap(x0, x1);
// swap(y0, y1);
}
int dx = x1 - x0;
int dy = y1 - y0;
float gradient = (float) dy / (float) dx; //TODO: float?
// handle first endpoint
float xend = Round(x0);
float yend = y0 + gradient * (xend - x0);
float xgap = rFractionalPart(x0 + 0.5f);
int xpxl1 = Mathf.RoundToInt(xend); //this will be used in the main loop
int ypxl1 = Mathf.RoundToInt(IntegerPart(yend));
if(steep) {
Plot(ypxl1, xpxl1, rFractionalPart(yend) * xgap, col);
Plot(ypxl1+1, xpxl1, FractionalPart(yend) * xgap, col);
} else {
Plot(xpxl1, ypxl1 , rFractionalPart(yend) * xgap, col);
Plot(xpxl1, ypxl1+1, FractionalPart(yend) * xgap, col);
}
float intery = yend + gradient; // first y-intersection for the main loop
// handle second endpoint
xend = Round(x1);
yend = y1 + gradient * (xend - x1);
xgap = FractionalPart(x1 + 0.5f);
int xpxl2 = Mathf.RoundToInt(xend); //this will be used in the main loop
int ypxl2 = Mathf.RoundToInt(IntegerPart(yend));
if (steep) {
Plot(ypxl2 , xpxl2, rFractionalPart(yend) * xgap, col);
Plot(ypxl2+1, xpxl2, FractionalPart(yend) * xgap, col);
} else {
Plot(xpxl2, ypxl2, rFractionalPart(yend) * xgap, col);
Plot(xpxl2, ypxl2+1, FractionalPart(yend) * xgap, col);
}
// main loop
for (int x = xpxl1 + 1; x < xpxl2 - 1; x++) { //for x from xpxl1 + 1 to xpxl2 - 1 do
if (steep) {
Plot(Mathf.RoundToInt(IntegerPart(intery)) , x, rFractionalPart(intery), col);
Plot(Mathf.RoundToInt(IntegerPart(intery)+1f), x, FractionalPart(intery), col);
} else {
Plot(x, Mathf.RoundToInt(IntegerPart (intery)), rFractionalPart(intery), col);
Plot(x, Mathf.RoundToInt(IntegerPart (intery)+1), FractionalPart(intery), col);
}
intery = intery + gradient;
}
}
void DrawAALineFloats(float x0, float y0, float x1, float y1, Color col) { //NEWEST. USE THIS!
//TEMP TEST: draw point at beginning and end
Plot(x0, y0, 1f, col);
Plot(x1, y1, 1f, col);
bool steep = Mathf.Abs(y1 - y0) > Mathf.Abs(x1 - x0);
if (steep) {
float t0 = x0;
x0 = y0;
y0 = t0;
float t1 = x1;
x1 = y1;
y1 = t1;
// swap(x0, y0);
// swap(x1, y1);
}
if (x0 > x1) {
float xT = x0;
x0 = x1;
x1 = xT;
float yT = y0;
y0 = y1;
y1 = yT;
// swap(x0, x1);
// swap(y0, y1);
}
float dx = x1 - x0;
float dy = y1 - y0;
float gradient = dy / dx; //TODO: float?
// handle first endpoint
float xend = Round(x0);
float yend = y0 + gradient * (xend - x0);
float xgap = rFractionalPart(x0 + 0.5f);
float xpxl1 = xend; //this will be used in the main loop
float ypxl1 = IntegerPart(yend);
if(steep) {
Plot(ypxl1, xpxl1, rFractionalPart(yend) * xgap, col);
Plot(ypxl1+1, xpxl1, FractionalPart(yend) * xgap, col);
} else {
Plot(xpxl1, ypxl1 , rFractionalPart(yend) * xgap, col);
Plot(xpxl1, ypxl1+1, FractionalPart(yend) * xgap, col);
}
float intery = yend + gradient; // first y-intersection for the main loop
// handle second endpoint
xend = Round(x1);
yend = y1 + gradient * (xend - x1);
xgap = FractionalPart(x1 + 0.5f);
float xpxl2 = xend; //this will be used in the main loop
float ypxl2 = IntegerPart(yend);
if (steep) {
Plot(ypxl2 , xpxl2, rFractionalPart(yend) * xgap, col);
Plot(ypxl2+1, xpxl2, FractionalPart(yend) * xgap, col);
} else {
Plot(xpxl2, ypxl2, rFractionalPart(yend) * xgap, col);
Plot(xpxl2, ypxl2+1, FractionalPart(yend) * xgap, col);
}
// main loop
for (float x = xpxl1 + 1; x < xpxl2 - 1; x++) { //for x from xpxl1 + 1 to xpxl2 - 1 do
if (steep) {
Plot(IntegerPart(intery) , x, rFractionalPart(intery), col);
Plot(IntegerPart(intery)+1f, x, FractionalPart(intery), col);
} else {
Plot(x, IntegerPart (intery), rFractionalPart(intery), col);
Plot(x, IntegerPart (intery)+1, FractionalPart(intery), col);
}
intery = intery + gradient;
}
}
}
@col000r
Copy link
Author

col000r commented May 13, 2014

Wasn't really sure which data formats to use, ended up doing one version that takes floats and one that takes ints. The result should be pretty much the same...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment