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

m
 
(6 intermediate revisions by 4 users not shown)
Line 7:
{{trans|Python}}
 
<syntaxhighlight lang="11l">T Colour = BVec3
Byte r, g, b
 
F ==(other)
R .r == other.r & .g == other.g & .b == other.b
 
F (r, g, b)
.r = r
.g = g
.b = b
 
V black = Colour(0, 0, 0)
Line 120 ⟶ 111:
+-----------------+
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Bitmap tools}}
Line 545 ⟶ 537:
.................
.................</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#">
Line 848 ⟶ 968:
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">
Line 1,170 ⟶ 1,408:
>> 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>
 
=={{header|Nim}}==
{{Trans|Ada}}
Line 1,857 ⟶ 2,172:
{{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,934 ⟶ 2,249:
static draw(alpha) {}
}</syntaxhighlight>
 
=={{header|XPL0}}==
[[File:CubicXPL0.png|right]]
1,481

edits