Curve that touches three points: Difference between revisions

added RPL
m (→‎{{header|ooRexx}}: add version to compute the circle (and many other things))
(added RPL)
 
(9 intermediate revisions by 7 users not shown)
Line 9:
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<langsyntaxhighlight Actionlang="action!">INCLUDE "H6:REALMATH.ACT"
 
TYPE Point=[INT x,y]
Line 130:
DO UNTIL CH#$FF OD
CH=$FF
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Curve_that_touches_three_points.png Screenshot from Atari 8-bit computer]
Line 136:
=={{header|Ada}}==
Find center and radius of circle that touches the 3 points. Solve with simple linear algebra. In this case no division by zero.
<langsyntaxhighlight Adalang="ada">with Ada.Text_Io;
with Ada.Numerics.Generic_Elementary_Functions;
 
Line 197:
Put ("Center : "); Put ("("); Put (Xc); Put (", "); Put (Yc); Put (")"); New_Line;
Put ("Radius : "); Put (R); New_Line;
end Three_Point_Circle;</langsyntaxhighlight>
{{out}}
<pre>
Line 205:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">QuadraticCurve(p1,p2,p3){ ; Y = aX^2 + bX + c
x1:=p1.1, y1:=p1.2, x2:=p2.1, y2:=p2.2, x3:=p3.1, y3:=p3.2
m:=x1-x2, n:=x3-x2, m:= ((m*n)<0?-1:1) * m
Line 212:
c:=y1 - a*x1**2 - b*x1
return [a,b,c]
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">P1 := [10,10], P2 := [100,200], P3 := [200,10]
v := QuadraticCurve(p1,p2,p3)
a := v.1, b:= v.2, c:= v.3
Line 220:
res .= "[" x ", " y "]`n"
}
MsgBox % "Y = " a " X^2 " (b>0?"+":"") b " X " (c>0?"+":"") c " `n" res</langsyntaxhighlight>
; for plotting, use code from [https://rosettacode.org/wiki/Plot_coordinate_pairs#AutoHotkey RosettaCode: Plot Coordinate Pairs]
Outputs:<pre>Y = -0.021111 X^2 +4.433333 X -32.222222
Line 226:
[100, 200.000000]
[200, 10.000000]</pre>
 
=={{header|F_Sharp|F#}}==
This task uses [[Lagrange_Interpolation#F#]]
<syntaxhighlight lang="fsharp">
// Curve that touches three points. Nigel Galloway: September 13th., 2023
open Plotly.NET
let points=let a=LIF([10;100;200],[10;200;10]).Expression in [10.0..200.0]|>List.map(fun n->(n,(Evaluate.evaluate (Map.ofList ["x",n]) a).RealValue))
Chart.Point(points)|>Chart.show
</syntaxhighlight>
{{out}}
[[File:C3p.png]]
 
=={{header|FreeBASIC}}==
{{trans|Ada}}
<syntaxhighlight lang="vb">' Point P1
Dim As Double X1 = 10.0
Dim As Double Y1 = 10.0
 
' Point P2
Dim As Double X2 = 100.0
Dim As Double Y2 = 200.0
 
' Point P3
Dim As Double X3 = 200.0
Dim As Double Y3 = 10.0
 
' Point P4 - midpoint between P1 and P2
Dim As Double X4 = (X1 + X2) / 2.0
Dim As Double Y4 = (Y1 + Y2) / 2.0
Dim As Double S4 = (Y2 - Y1) / (X2 - X1) ' Slope P1-P2
Dim As Double A4 = -1.0 / S4 ' Slope P4-Center
' Y4 = A4 * X4 + B4 <=> B4 = Y4 - A4 * X4
Dim As Double B4 = Y4 - A4 * X4
 
' Point P5 - midpoint between P2 and P3
Dim As Double X5 = (X2 + X3) / 2.0
Dim As Double Y5 = (Y2 + Y3) / 2.0
Dim As Double S5 = (Y3 - Y2) / (X3 - X2) ' Slope P2-P3
Dim As Double A5 = -1.0 / S5 ' Slope P5-Center
' Y5 = A5 * X5 + B5 <=> B5 = Y5 - A5 * X5
Dim As Double B5 = Y5 - A5 * X5
 
' Find center
' Y = A4 * X + B4 ' Line 1
' Y = A5 * X + B5 ' Line 2
' Solve for X:
' A4 * X + B4 = A5 * X + B5
' A4 * X - A5 * X = B5 - B4
' X * (A4 - A5) = B5 - B4
' X = (B5 - B4) / (A4 - A5)
Dim As Double Xc = (B5 - B4) / (A4 - A5)
Dim As Double Yc = A4 * Xc + B4
' Radius
Dim As Double R = Sqr((X1 - Xc) ^ 2 + (Y1 - Yc) ^ 2)
 
Print Using "Center : (###.#, ###.#)"; Xc; Yc
Print Using "Radius : ###.#"; R
 
Sleep</syntaxhighlight>
 
=={{header|Go}}==
Line 235 ⟶ 294:
 
The resulting 'curve' is then saved to a .png file where it can be viewed with a utility such as EOG.
<langsyntaxhighlight lang="go">package main
 
import "github.com/fogleman/gg"
Line 274 ⟶ 333:
dc.Stroke()
dc.SavePNG("quadratic_curve.png")
}</langsyntaxhighlight>
 
=={{header|J}}==
Line 327 ⟶ 386:
 
=={{header|Julia}}==
To make things more specific, findthe example below finds the circle determined by the points. The curve is then the arc between the 3 points.
<langsyntaxhighlight lang="julia">using MakiePlots
 
struct Point; x::Float64; y::Float64; end
Line 353 ⟶ 412:
x = a-r:0.25:a+r
y0 = sqrt.(r^2 .- (x .- a).^2)
sceneplt = linesplot(x, y0 .+ b, color = :red)
linesplot!(scene, x, b .- y0, color = :red)
scatter!(scene, [p.x for p in allp], [p.y for p in allp], markersize = r / 10)
</langsyntaxhighlight>{{out}}
<pre>
The circle with center at x = 105.0, y = 81.31578947368422 and radius 118.78948534384199.
</pre>
[[File:Circle3points.png]]
 
=={{header|Lambdatalk}}==
Line 366 ⟶ 426:
 
===bezier interpolation of 3 points===
<syntaxhighlight lang="scheme">
<lang Scheme>
p(t) = 1*p0(1-t)2 + 2*p1(1-t)t + 1*p2t2
 
Line 378 ⟶ 438:
{* 1 {A.get 1 :p2} :t :t}} }}
-> interpol
</syntaxhighlight>
</lang>
 
===two useful functions===
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def middle
{lambda {:p1 :p2} // compute the middle point of p1 and p2
Line 396 ⟶ 456:
{- {* 2 {A.get 1 :p2}} {A.get 1 :p1} } }}}
-> symetric
</syntaxhighlight>
</lang>
 
===computing the curve===
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def curve
{lambda {:pol :n}
Line 408 ⟶ 468:
{S.serie -1 {+ :n 1}} }}}
-> curve
</syntaxhighlight>
</lang>
 
===drawing a point===
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def dot
{lambda {:pt}
Line 419 ⟶ 479:
stroke="#0ff" fill="transparent" stroke-width="2"}}}}
-> dot
</syntaxhighlight>
</lang>
 
===defining points===
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{def P0 {A.new 150 180}} -> P0
{def P1 {A.new 300 250}} -> P1
Line 436 ⟶ 496:
{def P21 {middle {P2} {P1}}} -> P21
{def P12 {symetric {P21} {P0}}} -> P12
</syntaxhighlight>
</lang>
 
===drawing points and curves===
 
<syntaxhighlight lang="scheme">
<lang Scheme>
{svg {@ width="500" height="500" style="background:#444;"}
{polyline {@ points="{curve {A.new {P0} {P20} {P2}} 20}"
Line 455 ⟶ 515:
{dot {P21}} {dot {P12}}
}
</syntaxhighlight>
</lang>
 
See the result in http://lambdaway.free.fr/lambdawalks/?view=bezier_3
Line 462 ⟶ 522:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
===Built-in===
<langsyntaxhighlight Mathematicalang="mathematica">pts = {{10, 10}, {100, 200}, {200, 10}};
cs = Circumsphere[pts]
Graphics[{PointSize[Large], Point[pts], cs}]</langsyntaxhighlight>
{{out}}
Outputs the circle:
Line 470 ⟶ 530:
and a graphical representation of the input points and the circle.
===Alternate implementation===
<langsyntaxhighlight Mathematicalang="mathematica">pts = {{10, 10}, {100, 200}, {200, 10}};
createCircle[{{x1_, y1_}, {x2_, y2_}, {x3_, y3_}}] :=
With[{a = Det[({{x1, y1, 1}, {x2, y2, 1}, {x3, y3, 1}})],
Line 481 ⟶ 541:
Circle[{-(d/(2 a)), -(e/(2 a))}, Sqrt[(d^2 + e^2)/(4 a^2) - f/a]]]
cs = createCircle[pts]
Graphics[{PointSize[Large], Point[pts], cs}]</langsyntaxhighlight>
{{out}}
Outputs the circle:
Line 490 ⟶ 550:
{{trans|Go}}
{{libheader|imageman}}
<langsyntaxhighlight Nimlang="nim">import imageman
 
type
Line 520 ⟶ 580:
let color = ColorRGBF([float32 0, 0, 0]) # Black.
img.drawPolyline(closed = false, color, P.points(N))
img.savePNG("curve.png", compression = 9)</langsyntaxhighlight>
 
=={{header|ooRexx}}==
===Version 1===
<langsyntaxhighlight lang="oorexx">/* REXX ***************************************************************
* Compute the polynome satisfying three given Points
**********************************************************************/
Line 613 ⟶ 673:
End
Select
When j=m Then Call ex 'WidersprüchlichesWidersprü�chliches Gleichungssystem'
When j>m Then Call ex 'Gleichungen sind linear abhängig'
Otherwise Nop
Line 647 ⟶ 707:
Exit
 
dbg: Return</langsyntaxhighlight>
{{out}}
<pre>y=-0.021111111111*x**2+4.43333333333*x-32.2222222222
Line 655 ⟶ 715:
200 / 10.0000008 / 10</pre>
===Version 2 using fraction arithmetic===
<langsyntaxhighlight lang="oorexx">/* REXX ***************************************************************
* Compute the polynome satisfying three given Points
**********************************************************************/
Line 758 ⟶ 818:
End
Select
When j=m Then Call ex 'WidersprüchlichesWidersprü�chliches Gleichungssystem'
When j>m Then Call ex 'Gleichungen sind linear abhängig'
Otherwise Nop
Line 922 ⟶ 982:
s=left(s,p-1)||new||substr(s,p+length(old))
End
Return s</langsyntaxhighlight>
{{out}}
<pre>y=-(19/900)*x**2+(133/30)*x-(290/9)
Line 930 ⟶ 990:
</pre>
===Version 3 computing the circumcircle (among many other things)===
<langsyntaxhighlight lang="oorexx">/* REXX ****************************************************************
* Triangle computes data about a given triangle
* The circumcircle is what we need here
Line 1,294 ⟶ 1,354:
Exit
 
::requires rxMath library</langsyntaxhighlight>
{{out}}
<pre>Triangle ABC:
Line 1,340 ⟶ 1,400:
 
=={{header|Perl}}==
[[File:Curve-3-points-perl.svg|300px|thumb|right]]
Hilbert '''curve''' task code repeated here, with the addition that the 3 task-required points are marked. Mostly satisfies the letter-of-the-law of task specification while (all in good fun) subverting the spirit of the thing.
Hilbert '''curve''' task code repeated here, with the addition that the 3 task-required points are marked. Satisfies the letter-of-the-law of task specification while (all in good fun) subverting the spirit of the thing.
<lang perl>use SVG;
<syntaxhighlight lang="perl">use SVG;
use List::Util qw(max min);
 
Line 1,384 ⟶ 1,445:
open $fh, '>', 'curve-3-points.svg';
print $fh $svg->xmlify(-namespace=>'svg');
close $fh;</langsyntaxhighlight>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/curve-3-points.svg Hilbert curve passing through 3 defined points] (offsite image)
 
=={{header|Phix}}==
Line 1,392 ⟶ 1,452:
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/Quadratic.htm here].
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 1,472 ⟶ 1,532:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|Raku}}==
Line 1,481 ⟶ 1,541:
Saved as a png for wide viewing support. Note that png coordinate systems have 0,0 in the upper left corner.
 
<syntaxhighlight lang="raku" perl6line>use Image::PNG::Portable;
 
# the points of interest
Line 1,570 ⟶ 1,630:
$png.set($x, $y, |@rgb) if ( $X - $x + ($Y - $y) × i ).abs <= $radius;
}
}</langsyntaxhighlight>
See [https://github.com/thundergnat/rc/blob/master/img/Curve-3-points-perl6.png Curve-3-points-perl6.png] (offsite .png image)
 
=={{header|RPL}}==
HP-49+ RPL has a built-in function named <code>LAGRANGE</code> that returns the curve equation from the 3 points, but let's consider it as belonging to a library.
{{works with|HP|48G}}
[[File:Parabol.png|thumb|right|alt=HP-48G emulator screenshot|HP-48G emulator screenshot]]
« → a b c
« { 0 0 0 }
c a - C→R SWAP / c b - RE /
b a - C→R SWAP / c b - RE / -
1 SWAP PUT
b a - C→R SWAP / OVER 1 GET b a + RE * -
2 SWAP PUT
a IM OVER 1 GET a RE SQ * - OVER 2 GET a RE * -
3 SWAP PUT
{ 'X^2' 'X' 1 } * ∑LIST
» » '<span style="color:blue">PAREQ</span>' STO
« # 131d # 64d PDIM 0 210 DUP2 XRNG YRNG
FUNCTION
(10,10) (100,200) (200,10)
3 DUPN <span style="color:blue">PAREQ</span> STEQ
ERASE DRAW
1 3 '''START''' PIXOFF '''NEXT''' <span style="color:grey">''@ switch off the 3 points on the curve''</span>
{ } PVIEW
{ PPAR EQ } PURGE
» '<span style="color:blue">TASK</span>' STO
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|DOME}}
<langsyntaxhighlight ecmascriptlang="wren">import "graphics" for Canvas, Color, Point
import "dome" for Window
 
Line 1,621 ⟶ 1,707:
}
}
}</langsyntaxhighlight>
 
=={{header|XPL0}}==
[[File:XPL0_Curve.gif|200px|thumb|right]]
<syntaxhighlight lang "XPL0">def X0=10., Y0=10., X1=100., Y1=200., X2=200., Y2=10.;
 
func real Lagrange(X);
real X;
return (X-X1) * (X-X2) / (X0-X1) / (X0-X2) * Y0 +
(X-X0) * (X-X2) / (X1-X0) / (X1-X2) * Y1 +
(X-X0) * (X-X1) / (X2-X0) / (X2-X1) * Y2;
 
def Offset = 205;
real X;
[SetVid($13); \VGA 320x200x8 graphics
X:= X0;
Move(fix(X), Offset-fix(Y0));
repeat X:= X + 1.;
Line(fix(X), Offset-fix(Lagrange(X)), 3\cyan\);
until X >= X2;
Point(fix(X0), Offset-fix(Y0), 14\yellow\);
Point(fix(X1), Offset-fix(Y1), 14);
Point(fix(X2), Offset-fix(Y2), 14);
]</syntaxhighlight>
 
=={{header|zkl}}==
Line 1,627 ⟶ 1,736:
Uses Image Magick and
the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
<langsyntaxhighlight lang="zkl">const X=0, Y=1; // p.X == p[X]
var p=L(L(10.0, 10.0), L(100.0, 200.0), L(200.0, 10.0)); // (x,y)
Line 1,661 ⟶ 1,770:
}
img.writeJPGFile("quadraticCurve.zkl.jpg");
}();</langsyntaxhighlight>
{{out}}
Image at [http://www.zenkinetic.com/Images/RosettaCode/quadraticCurve.zkl.jpg quadratic curve]
1,150

edits