15
2012
Xiaolin Wu’s line algorithm to Unity Javascript

Converted this function to Unity3D Javascript : http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
(Still has few bugs left..see that vertical line in screenshot..)
Webplayer:
coming later
Can anyone find the error in this code? Why doesnt it draw vertical lines..?
!note, couple lines are commented out, swapping x<>y,
if I enable that, line position doesnt match with mouse click.
// Xiaolin Wu's line algorithm - converted to unity- mgear - http://unitycoder.com/blog
// original source: http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
// *attach this scrip to a plane, then draw with mouse: click startpoint, click endpoint
private var texture:Texture2D;
public var texture_width:int=256;
public var texture_height:int=256;
private var point1:boolean = false;
private var point2:boolean = false;
private var startpoint:Vector2;
private var endpoint:Vector2;
function Start()
{
texture = new Texture2D (texture_width, texture_height);
renderer.material.mainTexture = texture;
}
function Update()
{
// draw lines with mouse
if (Input.GetMouseButtonDown(0))
{
var ray:Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit:RaycastHit;
if (Physics.Raycast(ray,hit, 100))
{
if (!point1)
{
pixelUV = hit.textureCoord;
pixelUV.x *= texture.width;
pixelUV.y *= texture.height;
startpoint = Vector2(pixelUV.x, pixelUV.y);
point1=true;
print (startpoint);
}else{
pixelUV = hit.textureCoord;
pixelUV.x *= texture.width;
pixelUV.y *= texture.height;
endpoint = Vector2(pixelUV.x, pixelUV.y);
point1=false;
drawLine(startpoint.x,startpoint.y,endpoint.x,endpoint.y);
print (endpoint);
}
}
}
}
// the actual code from wiki :
function plot(x, y, c)
{
texture.SetPixel (x,y,Color(c,c,c,1));
}
function ipart(x)
{
return Mathf.Floor(x);
}
function round(x)
{
return Mathf.RoundToInt(x+0.5);
}
function fpart(x)
{
return x - ipart(x);
}
function rfpart(x)
{
return 1 - fpart(x);
}
function drawLine(x1,y1,x2,y2)
{
var dx:float = x2 - x1;
var dy:float = y2 - y1;
if (Mathf.Abs(dx) < Mathf.Abs(dy))
{
// ** Commented these out, I dont get it how / why x & y should be swapped..?
// tmp = x1; x1=x2; x2=tmp;
// tmp = y1; y1=y2; y2=tmp;
// tmp = dx; dx=dy; dy=tmp;
}
if (x2 < x1)
{
tmp = x1; x1=x2; x2=tmp;
tmp = y1; y1=y2; y2=tmp;
}
gradient = dy / dx;
// handle first endpoint
xend = round(x1);
yend = y1 + gradient * (xend - x1);
xgap = rfpart(x1 + 0.5);
xpxl1 = xend; // this will be used in the main loop
ypxl1 = ipart(yend);
plot(xpxl1, ypxl1, rfpart(yend) * xgap);
plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap);
intery = yend + gradient; // first y-intersection for the main loop
// handle second endpoint
xend = round (x2);
yend = y2 + gradient * (xend - x2);
xgap = fpart(x2 + 0.5);
xpxl2 = xend; // this will be used in the main loop
ypxl2 = ipart (yend);
plot (xpxl2, ypxl2, rfpart (yend) * xgap);
plot (xpxl2, ypxl2 + 1, fpart (yend) * xgap);
// main drawing loop
for (x=xpxl1+1;x<xpxl2-1;x++)
{
plot (x, ipart (intery), rfpart (intery));
plot (x, ipart (intery) + 1, fpart (intery));
intery = intery + gradient;
}
texture.Apply();
}
Related Posts
1 Comment + Add Comment
Leave a comment
Recent posts
- Convert LAS/LAZ/PLY pointclouds to GLTF (GLB) Point Meshes (standalone converter)
- Detect SRP (URP or HDRP) with Assembly Definition Version Defines
- [LudumDare57] Theme: Depths
- MotionVector Effect: Object “disappears” when paused
- [GreaseMonkey] Unity Forum Fixer
- UnityHub: Make Hub application background Translucent
- Customize SpriteShapeRenderer quality (but has issues)
- Editor tool: Copy selected gameobject’s names into clipboard as rows (for Excel)
- Editor tool: Replace string in selected gameobject’s names
- UnityHub: Enable built-in Login Dialog (no more browser login/logout issues!)
- Use TikTok-TTS in Unity (with WebRequest)
- Create Scene Thumbnail Image using OnSceneSaved & OnPreviewGUI
Recent Comments
- on Vector3 maths for dummies!
- on UnityHub 3.6.0: Remove Version Control & Cloud Dashboard columns
- on Using RenderDoc with Unity (graphics debugger)
- on UI Scroll View automatic Content height
- on [Asset Store] Point Cloud Viewer & Tools
- on [Asset Store] Point Cloud Viewer & Tools
- on Vector3 maths for dummies!
- on UnityHub: Make Hub application background Translucent
An article by












The reason to swap x and y is that you want the algorithm to be running down a gradient -1<=y/x<=+1, otherwise it'll skip pixels along the line (as is happening without it). By swapping them, you effectively guarantee instead that -1<=x/y<=+1. However, you then have an algorithm that's running along the y axis in unit steps and accumulating the (smaller in magnitude) x- increment, instead of accumulating multiples of the gradient as you move along the x-axis in unit steps (the unswapped action). As a result, and if you swap them, each and every call to plot needs to have its first two arguments swapped over as well. (More formally, x* is y*, so need to be the second arguments in the calls to plot; the calculated/accumulated 'y-coordinates' produced by the algorithm are actually the x-coordinates so should be the first arguments.)
AL