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

imported>Chinhouse
 
(4 intermediate revisions by 3 users not shown)
Line 293:
#undef plot
#undef line</syntaxhighlight>
 
 
 
=={{header|Commodore Basic}}==
<syntaxhighlight lang="basic">
10 rem bezier curve algorihm
20 rem translated from purebasic
30 ns=25 : rem num segments
40 dim pt(ns,2) : rem points in line
50 sc=1024 : rem start of screen memory
60 sw=40 : rem screen width
70 sh=25 : rem screen height
80 pc=42 : rem plot character '*'
90 dim bp(2,1) : rem bezier curve points
100 bp(0,0)=1:bp(1,0)=70:bp(2,0)=1
110 bp(0,1)=1:bp(1,1)=8:bp(2,1)=23
120 dim pt%(ns,2) : rem individual lines in curve
130 gosub 3000
140 end
1000 rem plot line
1010 se=0 : rem 0 = steep 1 = !steep
1020 if abs(y1-y0)>abs(x1-x0) then se=1:tp=y0:y0=x0:x0=tp:tp=y1:y1=x1:x1=tp
1030 if x0>x1 then tp=x1:x1=x0:x0=tp:tp=y1:y1=y0:y0=tp
1040 dx=x1-x0
1050 dy=abs(y1-y0)
1060 er=dx/2
1070 y=y0
1080 ys=-1
1090 if y0<y1 then ys = 1
1100 for x=x0 to x1
1110 if se=1 then p0=y: p1=x:gosub 2000:goto 1130
1120 p0=x: p1=y: gosub 2000
1130 er=er-dy
1140 if er<0 then y=y+ys:er=er+dx
1150 next x
1160 return
2000 rem plot individual point
2010 rem p0 == plot point x
2020 rem p1 == plot point y
2030 sl=p0+(p1*sw)
2040 rem make sure we dont write beyond screen memory
2050 if sl<(sw*sh) then poke sc+sl,pc
2060 return
3000 rem bezier curve
3010 for i=0 to ns
3020 t=i/ns
3030 t1=1.0-t
3040 a=t1^2
3050 b=2.0*t*t1
3060 c=t^2
3070 pt(i,0)=a*bp(0,0)+b*bp(1,0)+c*bp(2,0)
3080 pt(i,1)=a*bp(0,1)+b*bp(1,1)+c*bp(2,1)
3090 next i
3100 for i=0 to ns-1
3110 x0=int(pt(i,0))
3120 y0=int(pt(i,1))
3130 x1=int(pt(i+1,0))
3140 y1=int(pt(i+1,1))
3150 gosub 1000
3160 next i
3170 return
</syntaxhighlight>
[https://www.worldofchris.com/assets/c64-bezier-curve.png Screenshot of Bézier curve on C64]
=={{header|D}}==
This solution uses two modules, from the Grayscale image and the Bresenham's line algorithm Tasks.
<syntaxhighlight lang="d">import grayscale_image, bitmap_bresenhams_line_algorithm;
 
struct Pt { int x, y; } // Signed.
 
void quadraticBezier(size_t nSegments=20, Color)
(Image!Color im, in Pt p1, in Pt p2, in Pt p3,
in Color color)
pure nothrow @nogc if (nSegments > 0) {
Pt[nSegments + 1] points = void;
 
foreach (immutable i, ref p; points) {
immutable double t = i / double(nSegments),
a = (1.0 - t) ^^ 2,
b = 2.0 * t * (1.0 - t),
c = t ^^ 2;
p = Pt(cast(typeof(Pt.x))(a * p1.x + b * p2.x + c * p3.x),
cast(typeof(Pt.y))(a * p1.y + b * p2.y + c * p3.y));
}
 
foreach (immutable i, immutable p; points[0 .. $ - 1])
im.drawLine(p.x, p.y, points[i + 1].x, points[i + 1].y, color);
}
 
void main() {
auto im = new Image!Gray(20, 20);
im.clear(Gray.white);
im.quadraticBezier(Pt(1,10), Pt(25,27), Pt(15,2), Gray.black);
im.textualShow();
}</syntaxhighlight>
{{out}}
<pre>....................
....................
...............#....
...............#....
...............#....
................#...
................#...
.................#..
.................#..
.................#..
.#...............#..
..##.............#..
....##...........#..
......#..........#..
.......#.........#..
........###......#..
...........######...
....................
....................
....................</pre>
 
 
Line 299 ⟶ 414:
{{libheader|SysUtils,StdCtrls}}
[[File:DelphiQuadBezier.png|frame|none]]
 
This code uses a Quadratic Bézier curve to create a Cardinal Spline, which is a much easier spline to use. You just provide a series of points and the spline will honor those points while creating a smooth curline line between the points.
 
<syntaxhighlight lang="Delphi">
Line 615 ⟶ 732:
</pre>
 
=={{header|Commodore Basic}}==
<syntaxhighlight lang="basic">
10 rem bezier curve algorihm
20 rem translated from purebasic
30 ns=25 : rem num segments
40 dim pt(ns,2) : rem points in line
50 sc=1024 : rem start of screen memory
60 sw=40 : rem screen width
70 sh=25 : rem screen height
80 pc=42 : rem plot character '*'
90 dim bp(2,1) : rem bezier curve points
100 bp(0,0)=1:bp(1,0)=70:bp(2,0)=1
110 bp(0,1)=1:bp(1,1)=8:bp(2,1)=23
120 dim pt%(ns,2) : rem individual lines in curve
130 gosub 3000
140 end
1000 rem plot line
1010 se=0 : rem 0 = steep 1 = !steep
1020 if abs(y1-y0)>abs(x1-x0) then se=1:tp=y0:y0=x0:x0=tp:tp=y1:y1=x1:x1=tp
1030 if x0>x1 then tp=x1:x1=x0:x0=tp:tp=y1:y1=y0:y0=tp
1040 dx=x1-x0
1050 dy=abs(y1-y0)
1060 er=dx/2
1070 y=y0
1080 ys=-1
1090 if y0<y1 then ys = 1
1100 for x=x0 to x1
1110 if se=1 then p0=y: p1=x:gosub 2000:goto 1130
1120 p0=x: p1=y: gosub 2000
1130 er=er-dy
1140 if er<0 then y=y+ys:er=er+dx
1150 next x
1160 return
2000 rem plot individual point
2010 rem p0 == plot point x
2020 rem p1 == plot point y
2030 sl=p0+(p1*sw)
2040 rem make sure we dont write beyond screen memory
2050 if sl<(sw*sh) then poke sc+sl,pc
2060 return
3000 rem bezier curve
3010 for i=0 to ns
3020 t=i/ns
3030 t1=1.0-t
3040 a=t1^2
3050 b=2.0*t*t1
3060 c=t^2
3070 pt(i,0)=a*bp(0,0)+b*bp(1,0)+c*bp(2,0)
3080 pt(i,1)=a*bp(0,1)+b*bp(1,1)+c*bp(2,1)
3090 next i
3100 for i=0 to ns-1
3110 x0=int(pt(i,0))
3120 y0=int(pt(i,1))
3130 x1=int(pt(i+1,0))
3140 y1=int(pt(i+1,1))
3150 gosub 1000
3160 next i
3170 return
</syntaxhighlight>
[https://www.worldofchris.com/assets/c64-bezier-curve.png Screenshot of Bézier curve on C64]
=={{header|D}}==
This solution uses two modules, from the Grayscale image and the Bresenham's line algorithm Tasks.
<syntaxhighlight lang="d">import grayscale_image, bitmap_bresenhams_line_algorithm;
 
struct Pt { int x, y; } // Signed.
 
void quadraticBezier(size_t nSegments=20, Color)
(Image!Color im, in Pt p1, in Pt p2, in Pt p3,
in Color color)
pure nothrow @nogc if (nSegments > 0) {
Pt[nSegments + 1] points = void;
 
foreach (immutable i, ref p; points) {
immutable double t = i / double(nSegments),
a = (1.0 - t) ^^ 2,
b = 2.0 * t * (1.0 - t),
c = t ^^ 2;
p = Pt(cast(typeof(Pt.x))(a * p1.x + b * p2.x + c * p3.x),
cast(typeof(Pt.y))(a * p1.y + b * p2.y + c * p3.y));
}
 
foreach (immutable i, immutable p; points[0 .. $ - 1])
im.drawLine(p.x, p.y, points[i + 1].x, points[i + 1].y, color);
}
 
void main() {
auto im = new Image!Gray(20, 20);
im.clear(Gray.white);
im.quadraticBezier(Pt(1,10), Pt(25,27), Pt(15,2), Gray.black);
im.textualShow();
}</syntaxhighlight>
{{out}}
<pre>....................
....................
...............#....
...............#....
...............#....
................#...
................#...
.................#..
.................#..
.................#..
.#...............#..
..##.............#..
....##...........#..
......#..........#..
.......#.........#..
........###......#..
...........######...
....................
....................
....................</pre>
=={{header|Factor}}==
Some code is shared with the cubic bezier task, but I put it here again to make it simple (hoping the two version don't diverge)
Line 1,329 ⟶ 1,334:
>> 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
 
quadraticBezier = function(img, p1, p2, p3, numPoints, colr)
points = []
for i in range(0, numPoints)
t = i / numPoints
u = 1 - t
a = u * u
b = 2 * t * u
c = t * t
x = floor(a * p1.x + b * p2.x + c * p3.x)
y = floor(a * p1.y + b * p2.y + c * p3.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, 55)
 
quadraticBezier bezier, p1, p2, p3, 20, color.red
gfx.clear
gfx.drawImage bezier, 0, 0
</syntaxhighlight>
 
=={{header|Nim}}==
{{trans|Ada}}
Line 1,709 ⟶ 1,789:
{{libheader|DOME}}
Requires version 1.3.0 of DOME or later.
<syntaxhighlight lang="ecmascriptwren">import "graphics" for Canvas, ImageData, Color, Point
import "dome" for Window
 
Line 1,784 ⟶ 1,864:
static draw(alpha) {}
}</syntaxhighlight>
 
=={{header|XPL0}}==
[[File:QuadXPL0.png|right]]
Anonymous user