Bitmap/Bézier curves/Cubic: Difference between revisions

no edit summary
m (syntax highlighting fixup automation)
imported>Chinhouse
No edit summary
(7 intermediate revisions by 5 users not shown)
Line 1:
[[Category:Geometry]]
{{task|Raster graphics operations}}
 
Using the data storage type defined [[Basic_bitmap_storage|on this page]] for raster images, and the <tt>draw_line</tt> function defined in [[Bresenham's_line_algorithm|this other one]], draw a '''cubic bezier curve'''
([[wp:Bezier_curves#Cubic_B.C3.A9zier_curves|definition on Wikipedia]]).
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T Colour
Byte r, g, b
 
Line 120:
+-----------------+
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Bitmap tools}}
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang=Action"action!">INCLUDE "H6:RGBLINE.ACT" ;from task Bresenham's line algorithm
INCLUDE "H6:REALMATH.ACT"
 
Line 254 ⟶ 253:
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/B%C3%A9zier_curves_cubic.png Screenshot from Atari 8-bit computer]
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">procedure Cubic_Bezier
( Picture : in out Image;
P1, P2, P3, P4 : Point;
Line 281 ⟶ 279:
end Cubic_Bezier;</syntaxhighlight>
The following test
<syntaxhighlight lang="ada"> X : Image (1..16, 1..16);
begin
Fill (X, White);
Line 305 ⟶ 303:
H
</pre>
 
=={{header|ALGOL 68}}==
{{trans|Ada}}
Line 311 ⟶ 308:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: prelude/Bitmap/Bezier_curves/Cubic.a68'''<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
 
cubic bezier OF class image :=
Line 336 ⟶ 333:
END # cubic bezier #;
 
SKIP</syntaxhighlight>'''File: test/Bitmap/Bezier_curves/Cubic.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
Line 368 ⟶ 365:
000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
</pre>
=={{header|ATS}}==
See [[Bresenham_tasks_in_ATS]].
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
[[Image:beziercubic_bbc.gif|right]]
<syntaxhighlight lang="bbcbasic"> Width% = 200
Height% = 200
Line 428 ⟶ 427:
"Interface" <tt>imglib.h</tt>.
 
<syntaxhighlight lang="c">void cubic_bezier(
image img,
unsigned int x1, unsigned int y1,
Line 438 ⟶ 437:
color_component b );</syntaxhighlight>
 
<syntaxhighlight lang="c">#include <math.h>
 
/* number of segments for the curve */
Line 492 ⟶ 491:
#undef plot
#undef line</syntaxhighlight>
 
=={{header|D}}==
This solution uses two modules, from the Grayscale image and Bresenham's line algorithm Tasks.
<syntaxhighlight lang="d">import grayscale_image, bitmap_bresenhams_line_algorithm;
 
struct Pt { int x, y; } // Signed.
Line 547 ⟶ 545:
.................
.................</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
[[File:DelphiCubicBezier.png|frame|none]]
 
<syntaxhighlight lang="Delphi">
 
{This code would normally be stored in a separate library, but they presented here for clarity}
 
type T2DVector=packed record
X,Y: double;
end;
 
type T2DLine = packed record
P1,P2: T2DVector;
end;
 
type T2DVectorArray = array of T2DVector;
 
 
function MakeVector2D(const X,Y: double): T2DVector;
{Create 2D Vector from X and Y}
begin
Result.X:=X;
Result.Y:=Y;
end;
 
 
 
 
procedure DoCubicSplineLine(Steps: Integer; L1,L2: T2DLine; ClearArray: boolean; var PG: T2DVectorArray);
{Do cubic Bezier spline between L1.P1 and L2.P1 }
{L1.P1 = Point1, L1.P2 = Control1, L2.P1=Control2, L2.P2 = Point2}
var P: Integer;
var V: T2DVector;
var T: double;
var A,B,C,D,E,F,G,H : double;
begin
if ClearArray then SetLength(PG,0);
A := L2.P2.X - (3 * L2.P1.X) + (3 * L1.P2.X) - L1.P1.X;
B := (3 * L2.P1.X) - (6 * L1.P2.X) + (3 * L1.P1.X);
C := (3 * L1.P2.X) - (3 * L1.P1.X);
D := L1.P1.X;
 
E := L2.P2.Y - (3 * L2.P1.Y) + (3 * L1.P2.Y) - L1.P1.Y;
F := (3 * L2.P1.Y) - (6 * L1.P2.Y) + (3 * L1.P1.Y);
G := (3 * L1.P2.Y) - (3 * L1.P1.Y);
H := L1.P1.Y;
 
for P:=0 to Steps-1 do
begin
T :=P / (Steps-1);
V.X := (((A * T) + B) * T + C) * T + D;
V.Y := (((E * T) + F) * T + G) * T + H;
SetLength(PG,Length(PG)+1);
PG[High(PG)]:=V;
end;
end;
 
procedure MarkPoint(Image: TImage; P: TPoint);
begin
Image.Canvas.Pen.Width:=2;
Image.Canvas.Pen.Color:=clRed;
Image.Canvas.MoveTo(Trunc(P.X-3),Trunc(P.Y-3));
Image.Canvas.LineTo(Trunc(P.X+3),Trunc(P.Y+3));
Image.Canvas.MoveTo(Trunc(P.X+3),Trunc(P.Y-3));
Image.Canvas.LineTo(Trunc(P.X-3),Trunc(P.Y+3));
end;
 
 
 
procedure DrawControlPoint(Image: TImage; L: T2DLine);
var P1,P2: TPoint;
begin
Image.Canvas.Pen.Width:=1;
Image.Canvas.Pen.Color:=clBlue;
P1:=Point(Trunc(L.P1.X),Trunc(L.P1.Y));
P2:=Point(Trunc(L.P2.X),Trunc(L.P2.Y));
 
Image.Canvas.MoveTo(P1.X,P1.Y);
Image.Canvas.LineTo(P2.X,P2.Y);
Image.Canvas.Pen.Color:=clRed;
MarkPoint(Image,P2);
end;
 
 
 
procedure DrawOneSpline(Image: TImage; L1,L2: T2DLine);
var PG: T2DVectorArray;
var I: integer;
begin
DoCubicSplineLine(20,L1,L2,True,PG);
DrawControlPoint(Image,L1);
DrawControlPoint(Image,L2);
 
Image.Canvas.Pen.Width:=2;
Image.Canvas.Pen.Color:=clRed;
Image.Canvas.MoveTo(Trunc(PG[0].X),Trunc(PG[0].Y));
for I:=1 to High(PG) do
Image.Canvas.LineTo(Trunc(PG[I].X),Trunc(PG[I].Y));
end;
 
procedure ShowBezierCurve(Image: TImage);
var L1,L2: T2DLine;
begin
L1.P1:=MakeVector2D(50,50);
L1.P2:=MakeVector2D(250,50);
L2.P1:=MakeVector2D(50,250);
L2.P2:=MakeVector2D(250,250);
DrawOneSpline(Image, L1,L2);
L1.P1:=MakeVector2D(250,250);
L1.P2:=MakeVector2D(450,250);
L2.P1:=MakeVector2D(250,50);
L2.P2:=MakeVector2D(450,50);
DrawOneSpline(Image, L1,L2);
 
 
Image.Invalidate;
end;
</syntaxhighlight>
{{out}}
<pre>
 
Elapsed Time: 1.171 ms.
</pre>
 
=={{header|F Sharp|F#}}==
<syntaxhighlight lang="f#">
/// Uses Vector<float> from Microsoft.FSharp.Math (in F# PowerPack)
module CubicBezier
Line 568 ⟶ 693:
 
</syntaxhighlight>
<syntaxhighlight lang="f#">
// For rendering..
let drawPoints points (canvas:System.Windows.Controls.Canvas) =
Line 583 ⟶ 708:
points |> List.fold renderPoint points.Head
</syntaxhighlight>
 
=={{header|Factor}}==
The points should probably be in a sequence...
<syntaxhighlight lang="factor">USING: arrays kernel locals math math.functions
rosettacode.raster.storage sequences ;
IN: rosettacode.raster.line
Line 611 ⟶ 735:
points-to-lines
{R,G,B} swap image draw-lines ;</syntaxhighlight>
 
=={{header|FBSL}}==
Windows' graphics origin is located at the bottom-left corner of device bitmap.
 
'''Translation of BBC BASIC using pure FBSL's built-in graphics functions:'''
<syntaxhighlight lang="qbasic">#DEFINE WM_LBUTTONDOWN 513
#DEFINE WM_CLOSE 16
 
Line 674 ⟶ 797:
END SUB</syntaxhighlight>
'''Output:''' [[File:FBSLBezierCube.PNG]]
 
=={{header|Fortran}}==
{{trans|C}}
Line 680 ⟶ 802:
This subroutine should go inside the <code>RCImagePrimitive</code> module (see [[Bresenham's line algorithm]])
 
<syntaxhighlight lang="fortran">subroutine cubic_bezier(img, p1, p2, p3, p4, color)
type(rgbimage), intent(inout) :: img
type(point), intent(in) :: p1, p2, p3, p4
Line 707 ⟶ 829:
 
end subroutine cubic_bezier</syntaxhighlight>
 
=={{header|FreeBASIC}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="freebasic">' version 01-11-2016
' compile with: fbc -s console
 
Line 775 ⟶ 896:
Sleep
End</syntaxhighlight>
 
=={{header|Go}}==
{{trans|C}}
<syntaxhighlight lang="go">package raster
 
const b3Seg = 30
Line 809 ⟶ 929:
Demonstration program:
[[File:GoBez3.png|thumb|right]]
<syntaxhighlight lang="go">package main
 
import (
Line 824 ⟶ 944:
}
}</syntaxhighlight>
 
=={{header|J}}==
'''Solution:'''<br>
See the [[J:Essays/Bernstein Polynomials|Bernstein Polynomials essay]] on the [[J:|J Wiki]].<br>
Uses code from [[Basic_bitmap_storage#J|Basic bitmap storage]], [[Bresenham's_line_algorithm#J|Bresenham's line algorithm]] and [[Midpoint_circle_algorithm#J|Midpoint circle algorithm]].
<syntaxhighlight lang="j">require 'numeric'
 
bik=: 2 : '((*&(u!v))@(^&u * ^&(v-u)@-.))'
Line 852 ⟶ 971:
 
'''Example usage:'''
<syntaxhighlight lang="j">myimg=: 0 0 255 makeRGB 300 300
]randomctrlpts=: ,3 2 ?@$ }:$ myimg NB. 3 control points - quadratic
]randomctrlpts=: ,4 2 ?@$ }:$ myimg NB. 4 control points - cubic
myimg=: ((2 ,.~ _2]\randomctrlpts);255 0 255) drawCircles myimg NB. draw control points
viewRGB (randomctrlpts; 255 255 0) drawBezier myimg NB. display image with bezier line</syntaxhighlight>
 
=={{header|Java}}==
Using the BasicBitmapStorage class from the [[Bitmap]] task to produce a runnable program.
<syntaxhighlight lang ="java">
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import javax.imageio.ImageIO;
 
public final class BezierCubic {
 
public static void main(String[] args) throws IOException {
final int width = 200;
final int height = 200;
BasicBitmapStorage bitmap = new BasicBitmapStorage(width, height);
bitmap.fill(Color.YELLOW);
Point point1 = new Point(0, 150);
Point point2 = new Point(30, 50);
Point point3 = new Point(120, 130);
Point point4 = new Point(160, 30);
bitmap.cubicBezier(point1, point2, point3, point4, Color.BLACK, 20);
File bezierFile = new File("CubicBezierJava.jpg");
ImageIO.write((RenderedImage) bitmap.getImage(), "jpg", bezierFile);
}
}
final class BasicBitmapStorage {
 
public BasicBitmapStorage(int width, int height) {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
public void fill(Color color) {
Graphics graphics = image.getGraphics();
graphics.setColor(color);
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
}
 
public Color getPixel(int x, int y) {
return new Color(image.getRGB(x, y));
}
public void setPixel(int x, int y, Color color) {
image.setRGB(x, y, color.getRGB());
}
public Image getImage() {
return image;
}
public void cubicBezier(
Point point1, Point point2, Point point3, Point point4, Color color, int intermediatePointCount) {
List<Point> points = new ArrayList<Point>();
for ( int i = 0; i <= intermediatePointCount; i++ ) {
final double t = (double) i / intermediatePointCount;
final double u = 1.0 - t;
final double a = u * u * u;
final double b = 3.0 * t * u * u;
final double c = 3.0 * t * t * u;
final double d = t * t * t;
final int x = (int) ( a * point1.x + b * point2.x + c * point3.x + d * point4.x );
final int y = (int) ( a * point1.y + b * point2.y + c * point3.y + d * point4.y );
points.add( new Point(x, y) );
setPixel(x, y, color);
}
for ( int i = 0; i < intermediatePointCount; i++ ) {
drawLine(points.get(i).x, points.get(i).y, points.get(i + 1).x, points.get(i + 1).y, color);
}
}
public void drawLine(int x0, int y0, int x1, int y1, Color color) {
final int dx = Math.abs(x1 - x0);
final int dy = Math.abs(y1 - y0);
final int xIncrement = x0 < x1 ? 1 : -1;
final int yIncrement = y0 < y1 ? 1 : -1;
int error = ( dx > dy ? dx : -dy ) / 2;
while ( x0 != x1 || y0 != y1 ) {
setPixel(x0, y0, color);
int error2 = error;
if ( error2 > -dx ) {
error -= dy;
x0 += xIncrement;
}
if ( error2 < dy ) {
error += dx;
y0 += yIncrement;
}
}
setPixel(x0, y0, color);
}
private BufferedImage image;
}
</syntaxhighlight>
{{ out }}
[[Media:CubicBezierJava.jpg]]
 
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">
function draw() {
var canvas = document.getElementById("container");
Line 911 ⟶ 1,147:
}
</syntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">using Images
 
function cubicbezier!(xy::Matrix,
Line 935 ⟶ 1,170:
xy = [16 1; 1 4; 3 16; 15 11]
cubicbezier!(xy)</syntaxhighlight>
 
=={{header|Kotlin}}==
This incorporates code from other relevant tasks in order to provide a runnable example.
<syntaxhighlight lang="scala">// Version 1.2.40
 
import java.awt.Color
Line 1,015 ⟶ 1,249:
}
}</syntaxhighlight>
 
=={{header|Lua}}==
Starting with the code from [[Bitmap/Bresenham's line algorithm#Lua|Bitmap/Bresenham's line algorithm]], then extending:
<syntaxhighlight lang=lua>Bitmap.cubicbezier = function(self, x1, y1, x2, y2, x3, y3, x4, y4, nseg)
nseg = nseg or 10
local prevx, prevy, currx, curry
for i = 0, nseg do
local t = i / nseg
local a, b, c, d = (1-t)^3, 3*t*(1-t)^2, 3*t^2*(1-t), t^3
prevx, prevy = currx, curry
currx = math.floor(a * x1 + b * x2 + c * x3 + d * x4 + 0.5)
curry = math.floor(a * y1 + b * y2 + c * y3 + d * y4 + 0.5)
if i > 0 then
self:line(prevx, prevy, currx, curry)
end
end
end
local bitmap = Bitmap(61,21)
bitmap:clear()
bitmap:cubicbezier( 1,1, 15,41, 45,-20, 59,19 )
bitmap:render({[0x000000]='.', [0xFFFFFFFF]='X'})</syntaxhighlight>
{{out}}
<pre>.............................................................
.X...........................................................
.X...........................................................
..X..........................................................
...X.........................................................
...X.....................................XXXXX...............
....X.................................XXX.....XXXX...........
....X..............................XXX............X..........
.....X...........................XX................X.........
.....X.........................XX...................X........
......X.....................XXX......................XX......
.......X..................XX..........................X......
........X...............XX.............................X.....
.........X...........XXX................................X....
..........XXXX....XXX...................................X....
..............XXXX.......................................X...
.........................................................X...
..........................................................X..
..........................................................X..
...........................................................X.
.............................................................</pre>
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
Drawing a cubic bezier curve out of any SVG or CANVAS frame.
1) interpolating 4 points
Line 1,137 ⟶ 1,326:
 
</syntaxhighlight>
=={{header|Lua}}==
 
Starting with the code from [[Bitmap/Bresenham's line algorithm#Lua|Bitmap/Bresenham's line algorithm]], then extending:
 
<syntaxhighlight lang="lua">Bitmap.cubicbezier = function(self, x1, y1, x2, y2, x3, y3, x4, y4, nseg)
nseg = nseg or 10
local prevx, prevy, currx, curry
for i = 0, nseg do
local t = i / nseg
local a, b, c, d = (1-t)^3, 3*t*(1-t)^2, 3*t^2*(1-t), t^3
prevx, prevy = currx, curry
currx = math.floor(a * x1 + b * x2 + c * x3 + d * x4 + 0.5)
curry = math.floor(a * y1 + b * y2 + c * y3 + d * y4 + 0.5)
if i > 0 then
self:line(prevx, prevy, currx, curry)
end
end
end
local bitmap = Bitmap(61,21)
bitmap:clear()
bitmap:cubicbezier( 1,1, 15,41, 45,-20, 59,19 )
bitmap:render({[0x000000]='.', [0xFFFFFFFF]='X'})</syntaxhighlight>
{{out}}
<pre>.............................................................
.X...........................................................
.X...........................................................
..X..........................................................
...X.........................................................
...X.....................................XXXXX...............
....X.................................XXX.....XXXX...........
....X..............................XXX............X..........
.....X...........................XX................X.........
.....X.........................XX...................X........
......X.....................XXX......................XX......
.......X..................XX..........................X......
........X...............XX.............................X.....
.........X...........XXX................................X....
..........XXXX....XXX...................................X....
..............XXXX.......................................X...
.........................................................X...
..........................................................X..
..........................................................X..
...........................................................X.
.............................................................</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">points= {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
Graphics[{BSplineCurve[points], Green, Line[points], Red, Point[points]}]</syntaxhighlight>
[[File:MmaCubicBezier.png]]
 
=={{header|MATLAB}}==
Note: Store this function in a file named "bezierCubic.mat" in the @Bitmap folder for the Bitmap class defined [[Bitmap#MATLAB|here]].
<syntaxhighlight lang=MATLAB"matlab">
function bezierCubic(obj,pixel_0,pixel_1,pixel_2,pixel_3,color,varargin)
 
Line 1,181 ⟶ 1,410:
Sample usage:
This will generate the image example for the PHP solution.
<syntaxhighlight lang=MATLAB"matlab">
>> img = Bitmap(200,200);
>> img.fill([255 255 255]);
>> img.bezierCubic([160 10],[10 40],[30 160],[150 110],[255 0 0],110);
>> disp(img)
</syntaxhighlight>
 
=={{header|MiniScript}}==
This GUI implementation is for use with [http://miniscript.org/MiniMicro Mini Micro].
<syntaxhighlight lang="miniscript">
Point = {"x": 0, "y":0}
Point.init = function(x, y)
p = new Point
p.x = x; p.y = y
return p
end function
 
drawLine = function(img, x0, y0, x1, y1, colr)
sign = function(a, b)
if a < b then return 1
return -1
end function
dx = abs(x1 - x0)
sx = sign(x0, x1)
dy = abs(y1 - y0)
sy = sign(y0, y1)
if dx > dy then
err = dx
else
err = -dy
end if
err = floor(err / 2)
while true
img.setPixel x0, y0, colr
if x0 == x1 and y0 == y1 then break
e2 = err
if e2 > -dx then
err -= dy
x0 += sx
end if
if e2 < dy then
err += dx
y0 += sy
end if
end while
end function
 
cubicBezier = function(img, p1, p2, p3, p4, numPoints, colr)
points = []
for i in range(0, numPoints)
t = i / numPoints
u = 1 - t
a = (1 - t)^3
b = 3 * t * (1 - t)^2
c = 3 * t^2 * (1 - t)
d = t^3
x = floor(a * p1.x + b * p2.x + c * p3.x + d * p4.x)
y = floor(a * p1.y + b * p2.y + c * p3.y + d * p4.y)
points.push(Point.init(x, y))
img.setPixel x, y, colr
end for
for i in range(1, numPoints)
drawLine img, points[i-1].x, points[i-1].y, points[i].x, points[i].y, colr
end for
end function
 
bezier = Image.create(480, 480)
p1 = Point.init(50, 100)
p2 = Point.init(200, 400)
p3 = Point.init(360, 0)
p4 = Point.init(300, 424)
 
cubicBezier bezier, p1, p2, p3, p4, 20, color.red
gfx.clear
gfx.drawImage bezier, 0, 0
</syntaxhighlight>
 
Line 1,191 ⟶ 1,496:
{{Trans|Ada}}
We use module “bitmap” for bitmap management and module “bresenham” to draw segments.
<syntaxhighlight lang=Nim"nim">import bitmap
import bresenham
import lenientops
Line 1,239 ⟶ 1,544:
H.........H.....
H...............</pre>
 
=={{header|OCaml}}==
 
<syntaxhighlight lang="ocaml">let cubic_bezier ~img ~color
~p1:(_x1, _y1)
~p2:(_x2, _y2)
Line 1,286 ⟶ 1,590:
by_pair pts (fun p0 p1 -> line ~p0 ~p1);
;;</syntaxhighlight>
 
=={{header|Phix}}==
Output similar to [[Bitmap/Bézier_curves/Cubic#Mathematica|Mathematica]]<br>
Requires new_image() from [[Bitmap#Phix|Bitmap]], bresLine() from [[Bitmap/Bresenham's_line_algorithm#Phix|Bresenham's_line_algorithm]], write_ppm() from [[Bitmap/Write_a_PPM_file#Phix|Write_a_PPM_file]]. <br>
Results may be verified with demo\rosetta\viewppm.exw
<syntaxhighlight lang=Phix"phix">-- demo\rosetta\Bitmap_BezierCubic.exw (runnable version)
include ppm.e -- black, green, red, white, new_image(), write_ppm(), bresLine() -- (covers above requirements)
 
Line 1,322 ⟶ 1,625:
img[300][100] = red
write_ppm("Bezier.ppm",img)</syntaxhighlight>
 
=={{header|PHP}}==
[[Image:Cubic bezier curve PHP.png|right]]
Line 1,334 ⟶ 1,636:
Outputs image to the right directly to browser or stdout.
 
<syntaxhighlight lang="php"><?
 
$image = imagecreate(200, 200);
Line 1,364 ⟶ 1,666:
}
</syntaxhighlight>
 
=={{header|PicoLisp}}==
This uses the 'brez' line drawing function from
[[Bitmap/Bresenham's line algorithm#PicoLisp]].
<syntaxhighlight lang=PicoLisp"picolisp">(scl 6)
 
(de cubicBezier (Img N X1 Y1 X2 Y2 X3 Y3 X4 Y4)
Line 1,393 ⟶ 1,694:
(inc 'Y DY) ) ) ) )</syntaxhighlight>
Test:
<syntaxhighlight lang=PicoLisp"picolisp">(let Img (make (do 200 (link (need 300 0)))) # Create image 300 x 200
(cubicBezier Img 24 20 120 540 33 -225 33 285 100)
(out "img.pbm" # Write to bitmap file
Line 1,401 ⟶ 1,702:
 
(call 'display "img.pbm")</syntaxhighlight>
 
=={{header|Processing}}==
<syntaxhighlight lang=Prolog"prolog">noFill();
bezier(85, 20, 10, 10, 90, 90, 15, 80);
/*
Line 1,412 ⟶ 1,712:
 
'''It can be run on line''' :<BR> [https://www.openprocessing.org/sketch/846556/ here.]
<syntaxhighlight lang="text">
float[] x = new float[4];
float[] y = new float[4];
Line 1,486 ⟶ 1,786:
}
</syntaxhighlight>
 
=={{header|PureBasic}}==
<syntaxhighlight lang=PureBasic"purebasic">Procedure cubic_bezier(img, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y, Color, n_seg)
Protected i
Protected.f t, t1, a, b, c, d
Line 1,524 ⟶ 1,823:
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow</syntaxhighlight>
 
=={{header|Python}}==
{{works with|Python|3.1}}
 
Extending the example given [[Bresenham's line algorithm#Python|here]] and using the algorithm from the C solution above:
<syntaxhighlight lang="python">def cubicbezier(self, x0, y0, x1, y1, x2, y2, x3, y3, n=20):
pts = []
for i in range(n+1):
Line 1,575 ⟶ 1,873:
+-----------------+
'''</syntaxhighlight>
 
=={{header|R}}==
<syntaxhighlight lang=R"r"># x, y: the x and y coordinates of the hull points
# n: the number of points in the curve.
bezierCurve <- function(x, y, n=10)
Line 1,616 ⟶ 1,913:
plot(x, y, "o", pch=20)
points(bezierCurve(x,y,20), type="l", col="red")</syntaxhighlight>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
(require racket/draw)
Line 1,646 ⟶ 1,942:
bm
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 1,652 ⟶ 1,947:
Uses pieces from [[Bitmap#Raku| Bitmap]], and [[Bitmap/Bresenham's_line_algorithm#Raku| Bresenham's line algorithm]] tasks. They are included here to make a complete, runnable program.
 
<syntaxhighlight lang="raku" line>class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
has UInt ($.width, $.height);
Line 1,753 ⟶ 2,048:
 
See [https://github.com/thundergnat/rc/blob/master/img/Bezier-cubic-perl6.png example image here], (converted to a .png as .ppm format is not widely supported).
 
=={{header|Ruby}}==
{{trans|Tcl}}
Line 1,759 ⟶ 2,053:
Requires code from the [[Bitmap#Ruby|Bitmap]] and [[Bitmap/Bresenham's line algorithm#Ruby Bresenham's line algorithm]] tasks
 
<syntaxhighlight lang="ruby">class Pixmap
def draw_bezier_curve(points, colour)
# ensure the points are increasing along the x-axis
Line 1,800 ⟶ 2,094:
points.each {|p| bitmap.draw_circle(p, 3, RGBColour::RED)}
bitmap.draw_bezier_curve(points, RGBColour::BLUE)</syntaxhighlight>
 
=={{header|Tcl}}==
{{libheader|Tk}}
This solution can be applied to any number of points. Uses code from [[Basic_bitmap_storage#Tcl|Basic bitmap storage]] (<tt>newImage</tt>, <tt>fill</tt>), [[Bresenham's_line_algorithm#Tcl|Bresenham's line algorithm]] (<tt>drawLine</tt>), and [[Midpoint_circle_algorithm#Tcl|Midpoint circle algorithm]] (<tt>drawCircle</tt>)
<syntaxhighlight lang="tcl">package require Tcl 8.5
package require Tk
 
Line 1,867 ⟶ 2,160:
 
[[Image:Tcl_cubic_bezier.png]]
 
=={{header|TI-89 BASIC}}==
 
{{TI-image-task}}
 
<syntaxhighlight lang="ti89b">Define cubic(p1,p2,p3,p4,segs) = Prgm
Local i,t,u,prev,pt
0 → pt
Line 1,885 ⟶ 2,177:
EndFor
EndPrgm</syntaxhighlight>
 
=={{header|Wren}}==
{{libheader|DOME}}
Requires version 1.3.0 of DOME or later.
<syntaxhighlight lang=ecmascript"wren">import "graphics" for Canvas, ImageData, Color, Point
import "dome" for Window
 
Line 1,969 ⟶ 2,260:
=={{header|XPL0}}==
[[File:CubicXPL0.png|right]]
<syntaxhighlight lang=XPL0"xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
proc Bezier(P0, P1, P2, P3); \Draw cubic Bezier curve
Line 2,004 ⟶ 2,295:
SetVid(3); \restore normal text display
]</syntaxhighlight>
 
=={{header|zkl}}==
[[File:CubicXPL0.png|right]]
Line 2,012 ⟶ 2,302:
 
Add this to the PPM class:
<syntaxhighlight lang="zkl"> fcn cBezier(p0x,p0y, p1x,p1y, p2x,p2y, p3x,p3y, rgb, numPts=500){
numPts.pump(Void,'wrap(t){ // B(t)
t=t.toFloat()/numPts; t1:=(1.0 - t);
Line 2,022 ⟶ 2,312:
}</syntaxhighlight>
Doesn't use line segments, they don't seem like an improvement.
<syntaxhighlight lang="zkl">bitmap:=PPM(200,150,0xff|ff|ff);
bitmap.cBezier(0,149, 30,50, 120,130, 160,30, 0);
bitmap.write(File("foo.ppm","wb"));</syntaxhighlight>
 
{{omit from|AWK}}
{{omit from|GUISS}}
{{omit from|PARI/GP}}
 
[[Category:Geometry]]
Anonymous user