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

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
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|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
[[Image:beziercubic_bbc.gif|right]]
<syntaxhighlight lang="bbcbasic"> Width% = 200
Height% = 200
Line 424 ⟶ 420:
LINE x%*2,y%*2,x%*2,y%*2
ENDPROC</syntaxhighlight>
 
=={{header|C}}==
"Interface" <tt>imglib.h</tt>.
 
<syntaxhighlight lang="c">void cubic_bezier(
image img,
unsigned int x1, unsigned int y1,
Line 438 ⟶ 433:
color_component b );</syntaxhighlight>
 
<syntaxhighlight lang="c">#include <math.h>
 
/* number of segments for the curve */
Line 492 ⟶ 487:
#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 ⟶ 541:
.................
.................</pre>
 
=={{header|F Sharp|F#}}==
<syntaxhighlight lang="f#">
/// Uses Vector<float> from Microsoft.FSharp.Math (in F# PowerPack)
module CubicBezier
Line 568 ⟶ 561:
 
</syntaxhighlight>
<syntaxhighlight lang="f#">
// For rendering..
let drawPoints points (canvas:System.Windows.Controls.Canvas) =
Line 583 ⟶ 576:
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 ⟶ 603:
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 ⟶ 665:
END SUB</syntaxhighlight>
'''Output:''' [[File:FBSLBezierCube.PNG]]
 
=={{header|Fortran}}==
{{trans|C}}
Line 680 ⟶ 670:
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 ⟶ 697:
 
end subroutine cubic_bezier</syntaxhighlight>
 
=={{header|FreeBASIC}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="freebasic">' version 01-11-2016
' compile with: fbc -s console
 
Line 775 ⟶ 764:
Sleep
End</syntaxhighlight>
 
=={{header|Go}}==
{{trans|C}}
<syntaxhighlight lang="go">package raster
 
const b3Seg = 30
Line 809 ⟶ 797:
Demonstration program:
[[File:GoBez3.png|thumb|right]]
<syntaxhighlight lang="go">package main
 
import (
Line 824 ⟶ 812:
}
}</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 ⟶ 839:
 
'''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|JavaScript}}==
<syntaxhighlight lang="javascript">
function draw() {
var canvas = document.getElementById("container");
Line 911 ⟶ 897:
}
</syntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">using Images
 
function cubicbezier!(xy::Matrix,
Line 935 ⟶ 920:
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 ⟶ 999:
}
}</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,076:
 
</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,160:
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]);
Line 1,187 ⟶ 1,166:
>> disp(img)
</syntaxhighlight>
 
=={{header|Nim}}==
{{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,217:
H.........H.....
H...............</pre>
 
=={{header|OCaml}}==
 
<syntaxhighlight lang="ocaml">let cubic_bezier ~img ~color
~p1:(_x1, _y1)
~p2:(_x2, _y2)
Line 1,286 ⟶ 1,263:
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,298:
img[300][100] = red
write_ppm("Bezier.ppm",img)</syntaxhighlight>
 
=={{header|PHP}}==
[[Image:Cubic bezier curve PHP.png|right]]
Line 1,334 ⟶ 1,309:
Outputs image to the right directly to browser or stdout.
 
<syntaxhighlight lang="php"><?
 
$image = imagecreate(200, 200);
Line 1,364 ⟶ 1,339:
}
</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,367:
(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,375:
 
(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,385:
 
'''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,459:
}
</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,496:
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,546:
+-----------------+
'''</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,586:
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,615:
bm
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
Line 1,652 ⟶ 1,620:
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 ⟶ 1,721:
 
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 ⟶ 1,726:
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 ⟶ 1,767:
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 ⟶ 1,833:
 
[[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 ⟶ 1,850:
EndFor
EndPrgm</syntaxhighlight>
 
=={{header|Wren}}==
{{libheader|DOME}}
Requires version 1.3.0 of DOME or later.
<syntaxhighlight lang="ecmascript">import "graphics" for Canvas, ImageData, Color, Point
import "dome" for Window
 
Line 1,966 ⟶ 1,930:
static draw(alpha) {}
}</syntaxhighlight>
 
=={{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 ⟶ 1,967:
SetVid(3); \restore normal text display
]</syntaxhighlight>
 
=={{header|zkl}}==
[[File:CubicXPL0.png|right]]
Line 2,012 ⟶ 1,974:
 
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 ⟶ 1,984:
}</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]]
10,327

edits