public static void DrawBezier(BezierPoint[] points, float rad, Color col, Texture2D tex) { rad = Mathf.Round(rad);//It is important to round the numbers otherwise it will mess up with the texture width if (points.Length <= 1) { return; } Vector2 topleft = new Vector2(Mathf.Infinity, Mathf.Infinity); Vector2 bottomright = new Vector2(0, 0); for (int i = 0; i < points.Length - 1; i++) { Vector2 main = points[i].main; Vector2 control2 = points[i].control2; Vector2 control1 = points[i + 1].control1; Vector2 main2 = points[i + 1].main; BezierCurve curve = new BezierCurve(main, control2, control1, main2); points[i].curve2 = curve; points[i + 1].curve1 = curve; topleft.x = Mathf.Min(topleft.x, curve.rect.x); topleft.y = Mathf.Min(topleft.y, curve.rect.y); bottomright.x = Mathf.Max(bottomright.x, curve.rect.x + curve.rect.width); bottomright.y = Mathf.Max(bottomright.y, curve.rect.y + curve.rect.height); } topleft -= new Vector2(rad, rad); bottomright += new Vector2(rad, rad); var start = new Vector2(Mathf.Clamp(topleft.x, 0, tex.width), Mathf.Clamp(topleft.y, 0, tex.height)); var width = new Vector2(Mathf.Clamp(bottomright.x - topleft.x, 0, tex.width - start.x), Mathf.Clamp(bottomright.y - topleft.y, 0, tex.height - start.y)); Color[] pixels = tex.GetPixels((int)start.x, (int)start.y, (int)width.x, (int)width.y, 0); for (var y = 0; y < width.y; y++) { for (var x = 0; x < width.x; x++) { var p = new Vector2(x + start.x, y + start.y); if (!Mathfx.IsNearBeziers(p, points, rad + 2)) { continue; } var samples = Sample(p); var c = Color.black; var pc = pixels[y * (int)width.x + x];//Previous pixel color for (var i = 0; i < samples.Length; i++) { if (Mathfx.IsNearBeziers(samples[i], points, rad)) { c += col; } else { c += pc; } } c /= samples.Length; pixels[y * (int)width.x + x] = c; } } tex.SetPixels((int)start.x, (int)start.y, (int)width.x, (int)width.y, pixels, 0); tex.Apply(); }
public static Texture2D DrawLine(Vector2 from, Vector2 to, float w, Color col, Texture2D tex, bool stroke, Color strokeCol, float strokeWidth) { w = Mathf.Round(w);//It is important to round the numbers otherwise it will mess up with the texture width strokeWidth = Mathf.Round(strokeWidth); var extent = w + strokeWidth; var stY = Mathf.Clamp(Mathf.Min(from.y, to.y) - extent, 0, tex.height);//This is the topmost Y value var stX = Mathf.Clamp(Mathf.Min(from.x, to.x) - extent, 0, tex.width); var endY = Mathf.Clamp(Mathf.Max(from.y, to.y) + extent, 0, tex.height); var endX = Mathf.Clamp(Mathf.Max(from.x, to.x) + extent, 0, tex.width);//This is the rightmost Y value strokeWidth = strokeWidth / 2; var strokeInner = (w - strokeWidth) * (w - strokeWidth); var strokeOuter = (w + strokeWidth) * (w + strokeWidth); var strokeOuter2 = (w + strokeWidth + 1) * (w + strokeWidth + 1); var sqrW = w * w;//It is much faster to calculate with squared values var lengthX = endX - stX; var lengthY = endY - stY; var start = new Vector2(stX, stY); Color[] pixels = tex.GetPixels((int)stX, (int)stY, (int)lengthX, (int)lengthY, 0);//Get all pixels for (int y = 0; y < lengthY; y++) { for (int x = 0; x < lengthX; x++) {//Loop through the pixels var p = new Vector2(x, y) + start; var center = p + new Vector2(0.5f, 0.5f); float dist = (center - Mathfx.NearestPointStrict(from, to, center)).sqrMagnitude;//The squared distance from the center of the pixels to the nearest point on the line if (dist <= strokeOuter2) { var samples = Sample(p); var c = Color.black; var pc = pixels[y * (int)lengthX + x]; for (int i = 0; i < samples.Length; i++) { //Loop through the samples dist = (samples[i] - Mathfx.NearestPointStrict(from, to, samples[i])).sqrMagnitude; //The squared distance from the sample to the line if (stroke) { if (dist <= strokeOuter && dist >= strokeInner) { c += strokeCol; } else if (dist < sqrW) { c += col; } else { c += pc; } } else { if (dist < sqrW) {//Is the distance smaller than the width of the line c += col; } else { c += pc;//No it wasn't, set it to be the original colour } } } c /= samples.Length;//Get the avarage colour pixels[y * (int)lengthX + x] = c; } } } tex.SetPixels((int)stX, (int)stY, (int)lengthX, (int)lengthY, pixels, 0); tex.Apply(); return(tex); }