Divide a rectangle into a number of unequal triangles: Difference between revisions

Added FreeBASIC
(Added Wren)
(Added FreeBASIC)
 
(20 intermediate revisions by 6 users not shown)
Line 11:
* Explain, or refer to the algorithm employed.
* Give a sample of sets of triangles produced from running the algorithm, on this page.
 
 
=={{header|FreeBASIC}}==
{{trans|WRen}}
<syntaxhighlight lang="vbnet">Randomize Timer
 
Function MINIMUM(arr() As Single) As Single
Dim As Single minVal = arr(Lbound(arr))
For i As Integer = Lbound(arr) To Ubound(arr)
If arr(i) < minVal Then minVal = arr(i)
Next i
Return minVal
End Function
Function MAXIMUM(arr() As Single) As Single
Dim As Single maxVal = arr(Lbound(arr))
For i As Integer = Lbound(arr) To Ubound(arr)
If arr(i) > maxVal Then maxVal = arr(i)
Next i
Return maxVal
End Function
 
Sub pointsOfRect(w As Integer, h As Integer, pts() As Single)
Redim As Single pts(1 To 4, 1 To 2)
pts(1, 1) = 0: pts(1, 2) = 0
pts(2, 1) = h: pts(2, 2) = 0
pts(3, 1) = h: pts(3, 2) = w
pts(4, 1) = 0: pts(4, 2) = w
End Sub
 
Function dist(p1() As Single, p2() As Single) As Single
Dim As Single dx = p2(1) - p1(1)
Dim As Single dy = p2(2) - p1(2)
Return Sqr(dx * dx + dy * dy)
End Function
 
Function area(tris() As Single, triIndex As Integer) As Single
Dim As Single aPoint(1 To 2)
Dim As Single bPoint(1 To 2)
aPoint(1) = tris(triIndex, 2, 1): aPoint(2) = tris(triIndex, 2, 2)
bPoint(1) = tris(triIndex, 1, 1): bPoint(2) = tris(triIndex, 1, 2)
Dim a As Single = dist(aPoint(), bPoint())
bPoint(1) = tris(triIndex, 3, 1): bPoint(2) = tris(triIndex, 3, 2)
Dim b As Single = dist(aPoint(), bPoint())
aPoint(1) = tris(triIndex, 1, 1): aPoint(2) = tris(triIndex, 1, 2)
Dim c As Single = dist(aPoint(), bPoint())
Dim s As Single = (a + b + c) * 0.5
Return Sqr(s * (s - a) * (s - b) * (s - c))
End Function
 
Sub divideRectIntoTris(w As Integer, h As Integer, n As Uinteger, tris() As Single)
Dim As Uinteger i, j, k
If n < 3 Then Print "'n' must be an integer >= 3.": Exit Sub 'END
Dim As Single pts(1 To 4, 1 To 2)
pointsOfRect(w, h, pts())
Dim As Single upper(1 To 3, 1 To 2)
For i = 1 To 3
For j = 1 To 2
upper(i, j) = pts(i, j)
Next j
Next i
Redim As Single tris(1 To n, 1 To 3, 1 To 2)
For i = 1 To 3
For j = 1 To 2
tris(1, i, j) = upper(i, j)
Next j
Next i
Dim As Single xs(1 To n)
xs(n) = w
Dim As Single lens(1 To n - 1)
Do
For i = 1 To n - 2
xs(i) = Rnd * w
Next i
' Sort xs
For i = 1 To n - 1
For j = i + 1 To n
If xs(i) > xs(j) Then Swap xs(i), xs(j)
Next j
Next i
For i = 1 To n - 1
lens(i) = xs(i + 1) - xs(i)
Next i
Loop Until MINIMUM(lens()) <> 0
For i = 1 To n - 1
Dim As Single tri(1 To 3, 1 To 2)
tri(1, 1) = xs(i): tri(1, 2) = 0
tri(2, 1) = pts(3, 1): tri(2, 2) = pts(3, 2)
tri(3, 1) = xs(i + 1): tri(3, 2) = 0
For j = 1 To 3
For k = 1 To 2
tris(i + 1, j, k) = tri(j, k)
Next k
Next j
Next i
End Sub
 
Dim As Single dims(1 To 2, 1 To 3)
dims(1, 1) = 20: dims(1, 2) = 10: dims(1, 3) = 4
dims(2, 1) = 30: dims(2, 2) = 20: dims(2, 3) = 8
Dim As Integer i, j, triIndex
Dim As Single w, h, n
For dimIndex As Uinteger = 1 To 2
w = dims(dimIndex, 1)
h = dims(dimIndex, 2)
n = dims(dimIndex, 3)
Print "A rectangle with a lower left vertex at (0, 0), width"; w; " and height"; h
Print "can be split into the following"; n; " triangles:"
Dim As Single tris(1 To n, 1 To 3, 1 To 2)
divideRectIntoTris(w, h, n, tris())
Dim As Single areas(1 To n)
Dim As Single tri(1 To 3, 1 To 2)
For triIndex = 1 To n
For i = 1 To 3
For j = 1 To 2
tri(i, j) = tris(triIndex, i, j)
Next j
Next i
areas(triIndex) = area(tris(), triIndex)
Next triIndex
If MINIMUM(areas()) <> MAXIMUM(areas()) Then
For triIndex = 1 To n
Print "[";
For i = 1 To 3
Print "[";
For j = 1 To 2
tri(i, j) = tris(triIndex, i, j)
Print Str(tri(i, j)); ",";
Next j
Print Chr(8); "], ";
Next i
Print Chr(8); Chr(8); "]"
Next triIndex
End If
Print
Next dimIndex
 
Sleep</syntaxhighlight>
{{out}}
<pre>A rectangle with a lower left vertex at (0, 0), width 20 and height 10
can be split into the following 4 triangles:
[[0,0], [10,0], [10,20]]
[[0,0], [10,20], [9.687466,0]]
[[9.687466,0], [10,20], [14.9594,0]]
[[14.9594,0], [10,20], [20,0]]
 
A rectangle with a lower left vertex at (0, 0), width 30 and height 20
can be split into the following 8 triangles:
[[0,0], [20,0], [20,30]]
[[0,0], [20,30], [3.175989,0]]
[[3.175989,0], [20,30], [4.040901,0]]
[[4.040901,0], [20,30], [10.83484,0]]
[[10.83484,0], [20,30], [15.34319,0]]
[[15.34319,0], [20,30], [16.37033,0]]
[[16.37033,0], [20,30], [21.38275,0]]
[[21.38275,0], [20,30], [30,0]]</pre>
 
=={{header|Julia}}==
The `cutrectangle` method creates a new triangle by consuming a previously created triangle by cutting it at a location determined by the ratio of two sequential primes, making for guaranteed noncongruence of all triangles thus made. The Luxor code is for the demo. See also <link>https://lynxview.com/temp/luxor-drawing.png</link>
<syntaxhighlight lang="julia">using Colors
using Luxor
using Primes
using Random
 
mutable struct Triangle
v1::Point
v2::Point
v3::Point
end
 
function cutrectangle(A, B, C, D, n)
n < 2 && error("Cannot cut rectangle into < 2 triangles")
triangles, i, j = [Triangle(A, B, C), Triangle(C, D, A)], 1, 2
for _ in 2:n-1
t = popfirst!(triangles)
p = Point(t.v3.x + i/(2j) * (t.v1.x - t.v3.x), t.v3.y + i/(2j) * (t.v1.y - t.v3.y))
push!(triangles, Triangle(t.v1, t.v2, p), Triangle(t.v2, t.v3, p))
i, j = j, nextprime(j + 1)
end
return triangles
end
 
colors = shuffle(collect(Colors.color_names))
idx = 1
Drawing(500, 500)
origin()
 
triangles = cutrectangle(Point(0.0, 0.0), Point(200.0, 0.0), Point(200.0, 200.0), Point(0.0, 200.0), 9)
 
for t in triangles
@show t
sethue(colors[mod1(idx, length(colors))][1])
poly([t.v1, t.v2, t.v3], :fill)
global idx += 1
end
 
finish()
preview()
</syntaxhighlight>{{out}}
<pre>
t = Triangle(Point(200.0, 0.0), Point(150.0, 150.0), Point(105.0, 105.0))
t = Triangle(Point(200.0, 0.0), Point(200.0, 200.0), Point(167.85714285714286, 96.42857142857143))
t = Triangle(Point(200.0, 200.0), Point(150.0, 150.0), Point(167.85714285714286, 96.42857142857143))
t = Triangle(Point(200.0, 200.0), Point(0.0, 200.0), Point(109.0909090909091, 109.0909090909091))
t = Triangle(Point(0.0, 200.0), Point(66.66666666666666, 66.66666666666666), Point(109.0909090909091, 109.0909090909091))
t = Triangle(Point(0.0, 200.0), Point(0.0, 0.0), Point(38.46153846153845, 123.07692307692307))
t = Triangle(Point(0.0, 0.0), Point(66.66666666666666, 66.66666666666666), Point(38.46153846153845, 123.07692307692307))
t = Triangle(Point(0.0, 0.0), Point(200.0, 0.0), Point(64.8529411764706, 64.8529411764706))
t = Triangle(Point(200.0, 0.0), Point(105.0, 105.0), Point(64.8529411764706, 64.8529411764706))
</pre>
 
=={{header|Perl}}==
All triangle vertices lie on the lengths and the corners and their locations are defined by ratios among two sequences with unique numbers. Since the height is the same but with different base for all triangles, none will share the area.
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use List::Util 'sum';
 
sub UnequalDivider {
my($L,$H,$N) = @_;
die unless $N > 2;
return (0,$H), (0,0), ((2/5)*$L,$H), ($L,0), ($L,$H) if $N == 3;
 
my ($fail,%unique,%ratios,@base,@roof,$bTotal,$rTotal);
 
do {
$fail = 0;
%unique = %ratios = () ;
++$unique{int(rand 2*$N) + 1} while keys %unique < $N;
my @segments = keys %unique;
@base = @segments[ 0 .. $N/2-1];
@roof = @segments[$N/2 .. $#segments];
($bTotal,$rTotal) = ( sum(@base), sum(@roof) );
++$ratios{$_/$bTotal} for (@base);
for (@roof) { if ( exists($ratios{$_/$rTotal}) ) { $fail = 1 && last } }
} until ( $fail == 0 );
 
my ($bPartial,$rPartial) = ( shift(@base), shift(@roof) );
my @vertices = ([0,$H], [0,0], [($rPartial/$rTotal)*$L,$H]);
 
for (0 .. @base) {
push @vertices, [$bPartial/$bTotal*$L,0];
if (@base == 1) {
0 == $N%2 ? return @vertices, ([$L,$H], [$L,0])
: return @vertices, ([$L*(1-$roof[-1]/$rTotal),$H], [$L,0], [$L,$H]);
}
($bPartial) += shift @base;
($rPartial) += shift @roof;
push @vertices, [$rPartial/$rTotal*$L,$H];
}
}
 
my @V = UnequalDivider(1000,500,7);
say sprintf( '(%.3f %.3f) 'x3, @{$V[$_]}, @{$V[++$_]}, @{$V[++$_]} ) =~ s/\.000//gr for 0 .. @V-3;</syntaxhighlight>
{{out}}
<pre>(0 500) (0 0) (352.941 500)
(0 0) (352.941 500) (520 0)
(352.941 500) (520 0) (529.412 500)
(520 0) (529.412 500) (680 0)
(529.412 500) (680 0) (588.235 500)
(680 0) (588.235 500) (1000 0)
(588.235 500) (1000 0) (1000 500)</pre>
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
Extending the approach suggested by Nigel Galloway I devised a scheme that needs no checking,
and penned a wee little interactive visualisation demo of it, that can be run [http://phix.x10.mx/p2js/SpliRT.htm here].
Should you find a way to make it draw similar triangles, shout out and let me know n and canvas size!
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo/rosetta/SpliRT.exw </span>
<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>
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Divide rectange into unequal triangles"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">help_text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
Press F1 to see this help text.
Let the rectangle/canvas be ABCD (clockwise) and
P be the leftmost point where Red and Blue touch, and
Q (if needed, aka n!=3) the rightmost vertex of the Green triangle.
The Red triangle (ACD) is a right angle triangle (no others will be).
The Blue triangle (BPC) is an isoceles triangle except when the canvas
is square and n=3, in which case P is 1/3 along AC (nearer A) making
BPC acture and ABP (Green) obtuse (and therefore non-similar).
For a non-square rectangle and n=3 one of BPC and ABP is always
acute and the other obtuse (and therefore non-similar).
The green triangle (AQP when n!=3, AQ==AB*0.6) is non-isoceles.
The remainder (QBP) is split equally along QB to create the remaining
n-3 triangles, drawn in black and white, and all of them are acute and non-isoceles and non-similar.
In that way, none of the triangles can be similar for any n and do not need checking.
Press +/- to alter n, resize the window to change the canvas/rectangle
size, which of course can be used to make it square or not square (the
canvas is initially square since that can be a bit fiddly).
"""</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">5</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">colour</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">colour</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasBegin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span><span style="color: #004600;">CD_FILL</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">cdCanvasEnd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">px</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">py</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">details</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">" (n=%d, rectangle %dx%d)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">title</span><span style="color: #0000FF;">&</span><span style="color: #000000;">details</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_RED</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetTextAlignment</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_CENTER</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasText</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"NOT POSSIBLE!"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}},</span><span style="color: #004600;">CD_RED</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">and</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">=</span><span style="color: #000000;">h</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}},</span><span style="color: #004600;">CD_BLUE</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}},</span><span style="color: #004600;">CD_GREEN</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">qx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">*</span><span style="color: #000000;">0.6</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">qd</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">-</span><span style="color: #000000;">qx</span><span style="color: #0000FF;">)/(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">qx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}},</span><span style="color: #004600;">CD_GREEN</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">bw</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">CD_WHITE</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">bw</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bw</span><span style="color: #0000FF;">=</span><span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">?</span><span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">:</span><span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">draw_triangle</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">qx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">px</span><span style="color: #0000FF;">,</span><span style="color: #000000;">py</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">qx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">qd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">h</span><span style="color: #0000FF;">}},</span><span style="color: #000000;">bw</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">qx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">qd</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">help_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandln</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupMessage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">help_text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bWrap</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*dlg*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">help_cb</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> <span style="color: #7060A8;">IupRedraw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #7060A8;">IupRedraw</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=500x500"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">),</span>
<span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s"`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttributeHandle</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"PARENTDIALOG"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
 
=={{header|Python}}==
Line 17 ⟶ 393:
It is assumed that the rectangle has its bottom left coordinate at (0,0) and is not rotated in the coordinate space, meaning that the location of the top-right corner of the rectangle is then enough to define it.
 
<langsyntaxhighlight lang="python">
import random
from typing import List, Union, Tuple
Line 68 ⟶ 444:
D C
 
Create the two extra lines D-p and p-C creating 3 triangles A-p-D, D-p-C and p-B-C. Now if distances A-p, p-B and B-C are all different, then the triangles will be different.
Now if distances A-p, p-B and B-C are all different, then the triangles will be different.
 
If we instead inserted **two** points between A-B, p0 and p1, we can insert **one** point q0, along D-C
Line 79 ⟶ 456:
 
We think of the L-to-R ordered top points as A p0 p1 then B; and the ordered l-to-R bottom points as D q0 then C.
* Create the triangles by using the i'th, (i+1)'th top points and the i'th bottom point; alternating with the (i)'th (i+1)'th bottom point and the (i+1)'th top point.
the (i)'th (i+1)'th bottom point and the (i+1)'th top point.
* Ensure the distances between successive top points, B-C, and successive bottom points are all different to get different triangles.
* If you insert `n`top points p, then you need `n-1` bottom points q.
Line 216 ⟶ 594:
print("\nrect_into_top_tri #2")
pp(rect_into_top_tri((2, 1), 4, 10))
</syntaxhighlight>
</lang>
 
{{out}}
Line 244 ⟶ 622:
((0, 0), (1.2, 1), (2, 1)),
((0, 0), (2, 1), (2, 0))]</pre>
 
=={{header|Raku}}==
The first triangle bisects the rectangle via the diagonal. The rest of them all got one vertex at the origin and a side defined by ratios of numbers from a descending positive integer sequence.
<syntaxhighlight lang="raku" line># 20220123 Raku programming solution
 
# Proof :
#
# H-----------A---------B-------C-----D---E
# | |
# | |
# | |
# O---------------------------------------L
#
# ▲OEL is unique as its area is the sum of the rest.
#
# and also in terms of area ▲OHA > ▲OAB > ... > ▲ODE
 
sub UnequalDivider (\L,\H,\N where N > 2) {
 
my \sum = $ = 0 ; my \part = $ = 0 ; my @sequence = (N^...1) ;
 
loop { # if ▲OHA ~ ▲OEL
sum = @sequence.sum; # increase 1st term
@sequence[0]*L*L/sum == H*H ?? (@sequence[0] +=1) !! last
}
 
( [ (0,0), (L,H), (L,0) ], ).Array.append: @sequence.map: -> \chunk {
[ (0,0), (L*part/sum,H), (L*(part+=chunk)/sum,H) ] ;
}
}
 
.say for UnequalDivider(1000,500,5);</syntaxhighlight>
{{out}}
<pre>
[(0 0) (1000 500) (1000 0)]
[(0 0) (0 500) (400 500)]
[(0 0) (400 500) (700 500)]
[(0 0) (700 500) (900 500)]
[(0 0) (900 500) (1000 500)]
</pre>
 
=={{header|Wren}}==
Line 253 ⟶ 672:
Assuming the rectangle is to be split into 'n' triangles where n >= 3, we first bisect the rectangle into two triangles, add the top one to the result list and then divide the bottom one into (n-1) triangles. We do this by choosing (n - 2) points at random on the bottom side of the rectangle which together with the two bottom vertices are such that, after sorting, the difference between successive pairs is never the same. We then link each pair of points with the upper right vertex of the rectangle to form the requisite number of triangles.
 
This process should ensure that all the triangles are different, albeit the first one is usually much larger than the others. However, to be absolutely sure, we check that the areas of all the triangles are different.
<langsyntaxhighlight ecmascriptlang="wren">import "random" for Random
import "./seq" for Lst
 
var rand = Random.new()
 
var pointsOfRect = Fn.new { |w, h| [[0, 0], [h, 0], [h, w], [0, w]] }
 
var dist = Fn.new { |p1, p2|
var dx = p2[0] - p1[0]
var dy = p2[1] - p1[1]
return (dx * dx + dy * dy).sqrt
}
 
// Heron's formula
var area = Fn.new { |tri|
var a = dist.call(tri[1], tri[0])
var b = dist.call(tri[2], tri[1])
var c = dist.call(tri[0], tri[2])
var s = (a + b + c) * 0.5
return (s * (s - a) * (s - b) * (s - c)).sqrt
}
 
var divideRectIntoTris = Fn.new { |w, h, n|
Line 294 ⟶ 729:
System.print("A rectangle with a lower left vertex at (0, 0), width %(w) and height %(h)")
System.print("can be split into the following %(n) triangles:")
 
System.print(divideRectIntoTris.call(w, h, n).join("\n"))
// make sure all triangles have different areas
while (true) {
var areas = []
var tris = divideRectIntoTris.call(w, h, n)
for (tri in tris) areas.add(area.call(tri))
if (Lst.distinct(areas).count == n) {
System.print(tris.join("\n"))
break
}
}
System.print()
}</langsyntaxhighlight>
 
{{out}}
2,130

edits