[Question]
  [
Given an integer \$n \geq 2\$, print a triangle of height \$n\$ of (triangles of height \$n\$ of asterisks), as in [this SO question](https://stackoverflow.com/q/69796358/257418).
For \$n=2\$, print:
```
    *
   ***
 *  *  *
*********
```
For \$n=3\$, print:
```
            *
           ***
          *****
       *    *    *
      ***  ***  ***
     ***************
  *    *    *    *    *
 ***  ***  ***  ***  ***
*************************
```
For \$n=4\$, print:
```
                        *
                       ***
                      *****
                     *******
                 *      *      *
                ***    ***    ***
               *****  *****  *****
              *********************
          *      *      *      *      *
         ***    ***    ***    ***    ***
        *****  *****  *****  *****  *****
       ***********************************
   *      *      *      *      *      *      *
  ***    ***    ***    ***    ***    ***    ***
 *****  *****  *****  *****  *****  *****  *****
*************************************************
```
And so on. Some rules:
* I write "print", but a function returning a string or list of lines is fine too.
* Trailing whitespace on each line is allowed, but not leading whitespace.
* Trailing blank lines are allowed.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"): write the shortest program you can, measured in bytes.
  
[Answer]
# [Python 3](https://docs.python.org/3/) with [numpy](https://numpy.org/doc/1.21/), ~~79~~ 74 bytes
```
lambda n:where(kron(*[c_[:n]>=abs(r_[1-n:n])]*2),*'* ')
from numpy import*
```
[Try it online!](https://tio.run/##FcnBCsIwDADQu1@RW5Oigu42mD9Sx@i0ZdU1KbEi@/qqx8crW12EuxaHa1t9nu8euP8sQQM@VRitu02u5/Ey@PmFOrnTgX@k0Z5pb40FQ7uokoHfuWyQchGttkVRWBMHSAwRO@qhaOKKxhwfkhj/R9S@ "Python 3 – Try It Online")
-5 thanks to ovs, with the use of `where`.
Step-by-step example of how it works:
```
>>> from numpy import*
>>> (n:=2)
2
>>> (Y:=c_[:n])
array([[0],
       [1]])
>>> (X:=r_[1-n:n])
array([-1,  0,  1])
>>> (Z:=Y>=abs(X))    # Broadcasts.
array([[False,  True, False],
       [ True,  True,  True]])
>>> (A:=kron(*[Z]*2))    # Listify, double, and unpack to give the same argument twice.
array([[False, False, False, False,  True, False, False, False, False],
       [False, False, False,  True,  True,  True, False, False, False],
       [False,  True, False, False,  True, False, False,  True, False],
       [ True,  True,  True,  True,  True,  True,  True,  True,  True]])
>>> (B:=where(A,*"* "))    # Select asterisk for true and space for false.
array([[' ', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', '*', '*', '*', ' ', ' ', ' '],
       [' ', '*', ' ', ' ', '*', ' ', ' ', '*', ' '],
       ['*', '*', '*', '*', '*', '*', '*', '*', '*']], dtype='<U1')
```
[Answer]
# [J](http://jsoftware.com/), 37 31 bytes
```
' *'{~[:,./^:2[:*/~i.>:/|@i:@<:
```
[Try it online!](https://tio.run/##y/qvpKeepmBrpaCuoKNgoGAFxLp6Cs5BPm7/1RW01Kvroq109PTjrIyirbT06zL17Kz0axwyrRxsrP5rcqUmZ@QrpCkYQRjq6jABY3QBE5jAfwA "J – Try It Online")
*-6 after seeing the phrase "Kronecker product" in m90's python answer, realizing that's what I was doing, and finding a golfier implementation in [this essay](https://code.jsoftware.com/wiki/Essays/Kronecker_Product).*
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~29~~ ~~16~~ 15 bytes
```
ZvG:!<~PtX*42*c
```
[**Try it online!**](https://tio.run/##y00syfn/P6rM3UrRpi6gJELLxEgr@f9/YwA)
### How it works
Consider input `3` as an example. The stack is shown upside down, with the most recent element below.
```
Zv    % Implicit input. Symmetric range
      % STACK: [1 2 3 2 1]
G:    % Push input again. Range
      % STACK: [1 2 3 2 1],
               [1 2 3]
!     % Transpose
      % STACK: [1 2 3 2 1],
               [1
                2
                3]
<~    % Less than?, negate; element-wise with broadcast
      % STACK: [1 1 1 1 1
                0 1 1 1 0
                0 0 1 0 0]
P     % Flip vertically
      % STACK: [0 0 1 0 0
                0 1 1 1 0
                1 1 1 1 1]
tX*   % Duplicate. Kronecker product
      % STACK: [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
                0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0
                0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
                0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
                0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0
                0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
                0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0
                0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0
                1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
42*   % Multiply by 42 (ASCII for '*'). Convert to char
      % Implicit display. Char 0 is displayed as space
      % STACK: ['            *            '
                '           ***           '
                '          *****          '
                '       *    *    *       '
                '      ***  ***  ***      '
                '     ***************     '
                '  *    *    *    *    *  '
                ' ***  ***  ***  ***  *** '
                '*************************']
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~160~~ ~~153~~ 148 bytes
```
p(c,n){n&&p(putchar(c),n-1);}r;t;l;i;f(n){for(r=0;r<n*n;p(10,1))for(t=r/n,l=r++%n,p(32,(n+~t)*(n*2-1)),i=t-~t;i--;p(32,n+~l))p(32,n+~l),p(42,l-~l);}
```
[Try it online!](https://tio.run/##VZDRbsIwDEXf@YoICeq0jqAFNmmm2ocMHqpAWaTMVGmmTavKp69LCwzIS2zf42vLWh207roKNLJseDqtoPr0@r1woCWySiW1jjxZMlRCQMqjA5fPya05ZqognWMqZV/1uZsx2twlyYSxgkWGwMnJyxg4zoKTRJN7dfJklKJBD7KV8haGrmWGVoWQ2s6wFx@FYZCiGYnw@oLf175@24pcNBkucIkrfMLnlgYgrCGgpwzv9t@BmdMlXIva/OyPJQz9cnbJ4nNKIkkG7jrpOo2Dx3niIG/pX61c0EsY98Rkt@ExCpY3ub8VPVjZAEIW9yeNL/@dG0R5hHa9el292Mf6hiO8ou2o7X51aYtD3amvPw "C (gcc) – Try It Online")
*Saved 7 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)!!!*
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 107 bytes
```
m,x,y;f(n){for(y=n*n;y--;)for(x*=x=m=2*n-1;x--;)putchar(abs(x%m-n+1)+y%n<n&abs(x/m-n+1)+y/n<n?42:x?32:10);}
```
[Try it online!](https://tio.run/##XcxBDoIwEEDRvccgwcwADVJwQ224iJvapGhiR0M1tiFc3QomLmT53@Jr1msdoy18EYQBwtHcBgiSMhKBMYFL@kx6aSXPiFXCL3p/PvRZDaBODnxqGeUV5iGlA22/VP6onKlreOu7mrfVDsUUrboQ4LgxwFHMIwfJkRIUM9RraNaw/4cpvrW5qt5F9voA "C (gcc) – Try It Online")
-1 byte by [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)
[Answer]
# [Python 3.8](https://docs.python.org/3.8/), ~~91~~ ~~86~~ 84 bytes
-2 bytes thanks to [Lynn](https://codegolf.stackexchange.com/users/3852/lynn)!
```
lambda n:[f"{(o%n*'**'+'*').center(w:=2*n-1)*(o//n*2+1):^{w*w}}"for o in range(n*n)]
```
[Try it online!](https://tio.run/##FchLCsIwEADQvacYCpKZKVrabiTQk/iBqIkWdBKGQJDSs0f6li/98jvKeEpaw3SpH/e9Px2IPYdmwbgXNsymNWzo@PCSvWKx08By6Ikxdp3w0PZkb0vhsq5NiAoRZgF18vIoLHStW@qWAUeyO4Cks2RUqn8 "Python 3.8 (pre-release) – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), 76 bytes
```
->n{(0...n*n).map{|i|((?**(i%n*2+1)).center(j=n*2-1)*(i/n*2+1)).center j*j}}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6vWsNAT08vTytPUy83saC6JrNGQ8NeS0sjUzVPy0jbUFNTLzk1ryS1SCPLFiiga6gJlNJHlVLI0sqqrf1fUFpSrJAWbRzLxaWsYVQBVKqgYFIRZ6RrUqFt@B8A "Ruby – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 25 bytes
```
ＮθＦθＦ⊕⊗ι«Ｊ×⊖⊗θ⁻κι×θιＧ↗↘θ*
```
[Try it online!](https://tio.run/##ZYqxDsIgFADn8hWkExgcXdqVpSYaY@oHtIgtEXiFgsYYvx2xujndXXJi7LyATqfU2CmGfTS99MTRGl3A4yx4YWOFl0baIM@EQ@x1pqKU4icqttFMLZBWGTkTLv9HRynDO2XjTK4Mq099Z7dUjYoD6McAllSn6aiGMTBccbjbn@etXJX5e6W0SeubfgM "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｎθ
```
Input `n`.
```
Ｆθ
```
Loop over each row.
```
Ｆ⊕⊗ι«
```
Loop over each of the `2i+1` triangles in each row.
```
Ｊ×⊖⊗θ⁻κι×θι
```
Jump to the (bottom left of the) triangle.
```
Ｇ↗↘θ*
```
Draw the triangle.
24 bytes if a leading blank line is allowed:
```
ＮθＦθ«Ｍ×⊖⊗θ⊗ιθＦ⊕⊗ι«Ｇ↖↙θ*←
```
[Try it online!](https://tio.run/##S85ILErOT8z5/98zr6C0xK80Nym1SKNQ05orLb9IAchQqObi9M0vS9UIycxNLdZwSU0uSs1NzStJTdFwyS9NygHShZqaOgowTiaIA9LPCTbAMw9TPVAJ2FjOgPycyvT8PA2r0AKf1LQSHQUrl/zyPAizUEdBSUsJZA7EeiuQMIhby1X7/7/pf92yHAA "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｎθ
```
Input `n`.
```
Ｆθ«
```
Loop over each row.
```
Ｍ×⊖⊗θ⊗ιθ
```
Jump to the end of the row.
```
Ｆ⊕⊗ι«
```
Loop over each of the `2i+1` triangles in each row.
```
Ｇ↖↙θ*
```
Draw the triangle.
```
←
```
Move to the next triangle.
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~82~~ 74 bytes
```
->n{(r=1.step n+=n-1,2).map{|x|r.map{|y|((?**y).center(n)*x).center n*n}}}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6vWqPI1lCvuCS1QCFP2zZP11DHSFMvN7GguqaipgjCqKzR0LDX0qrU1EtOzStJLdLI09SqgHEU8rTyamtr/xeUlhQrpEUbx/4HAA "Ruby – Try It Online")
Good golfers copy, great golfers steal.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `j`, 25 bytes
```
d‹£²ʁƛ?%›‛***Ḣ¥⋏n?ḭd›*¥²⋏
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=j&code=d%E2%80%B9%C2%A3%C2%B2%CA%81%C6%9B%3F%25%E2%80%BA%E2%80%9B***%E1%B8%A2%C2%A5%E2%8B%8Fn%3F%E1%B8%ADd%E2%80%BA*%C2%A5%C2%B2%E2%8B%8F&inputs=3&header=&footer=)
I think mirroring might help, but cannot think of how
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `C`, 15 bytes
```
ƛd‹?ɾ×*vømøĊ*;f
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=C&code=%C6%9Bd%E2%80%B9%3F%C9%BE%C3%97*v%C3%B8m%C3%B8%C4%8A*%3Bf&inputs=3&header=&footer=)
```
ƛ            ;  # Map 1...n to...
   ?ɾ           # 1...input...
     ×*         # Asterisks
       vøm      # Each palindromised
          øĊ    # Centered
            *   # Repeated...
 d‹             # (2 * value) - 1 times
              f # Flatten
                # (C flag) output centered
```
17 bytes without the flag by appending a `øĊ`.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~18 17~~ 16 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
ÇÑÄ
ïÈçYçÑ ûUÌÃû
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=x9HECu/I51nn0SD7VczD%2bw&input=MwotUg)
```
o_ÑÄ         - range [0..input] *2+1
ï          - pair each with itself
 È         - then pass pairs by f(X,Y)
  ç        - repeat result X times
   YçÑ    - repeat '*' Y times
ûNÑÉ       - centre pad
Ãû         - centre pad all
```
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~111~~ 100 bytes
```
f=lambda n,b=['*'],p=1:p>2 and b or f(n,[f'{2*r*l+l:^{(2*n-1)**p}}'for r in range(n)for l in b],p+1)
```
[Try it online!](https://tio.run/##dYyxCsIwFAD3fsXbkrzGIamDBOKPFIWEGi3E1/DoIqXfHttFdHC9O6685sdE3alwrcnn8IxDANLR9wLFRRdvXDlbCDRAhIkhSdJ9EotFxtxmd12kRToYhVjWVaQtYRgJOND9JkntIO8gbrPWqPopkrTKNQCFR5olq@bLdH/N8cfUNw "Python 3.8 (pre-release) – Try It Online")
Nowhere near the best Python 3 answers, but it's got recursion. See [my answer](https://stackoverflow.com/a/69804532/8164958) on the source SO question for an ungolfed version with the same mechanisms.
*-11 bytes thanks to @ovs*
[Answer]
# [R](https://www.r-project.org/), 82 bytes
```
function(n)write(c(" ","*")[1+(z=outer(c(n:1,2:n),1:n,"<="))%x%z],1,(2*n-1)^2,,"")
```
[Try it online!](https://tio.run/##DcgxCoAwDAXQ3VOUQCFf45C6FT2J6CIWXCKUiuLlq298uSY39q6my7ZynMaGOx9l543JkVBLmLXjdzqvsud/LaqEaBCNJjROBPjHv4uocGitV6xBhAg1cUCTeED9AA "R – Try It Online")
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 39 bytes
```
YPZ0Xa-_.1X_M\,a(J*Z_M_*^yMMy)TRt"* "Jn
```
[Replit!](https://replit.com/@dloscutoff/pip) Or, here's a 41-byte equivalent in Pip Classic: [Try it online!](https://tio.run/##K8gs@P8/MiDKICJRN17PMCLeN0YnUaPaSysqsdY3Xiuu0te3UjMkqERJS0HJK@/////GAA "Pip – Try It Online")
### Explanation
We create a structure out of 0's and 1's and then use it for both the micro- and macro-structure of the desired output.
```
YPZ0Xa-_.1X_M\,a
               a  First command-line argument
             \,   Inclusive range from 1 to that number
            M     To each element of that range, map this function:
     a-_           a minus the function argument
   0X              That many 0's
           _       Function argument
         1X        That many 1's
        .          Concatenate those two strings
 PZ                Palindromize
Y                 Yank the resulting list of strings into the y variable
```
For example, with an input of 3, `y` is `[00100; 01110; 11111]`.
```
(J*Z_M_*^yMMy)TRt"* "Jn
          MMy            Map this function to each character of each string in y:
         y                Take another copy of y
        ^                 Split it into a list of lists of characters
      _*                  Multiply each character by the function argument
     M                   To each sublist of the resulting list, map this function:
   Z_                     Transpose
 J*                       Join each sublist of the transposition into a single string
(            )TR         Transliterate the result:
                t         Replace characters "10"
                 "* "     with characters "* "
                     Jn  Join on newlines
```
[Answer]
# [Julia 1.0](http://julialang.org/), 68 bytes
```
~n=2n-1
!n=[' '^(2n^2-j*~n-i)*rpad('*'^~i,~n)^~j for i=1:n,j=1:n][:]
```
[Try it online!](https://tio.run/##HYg9CgMhFAZ7T/G28oe1UEgjeJJlBcEEnsgX2SSQNF7dJDvFwEx9Nc7uPedA9LBOLIibJJmUR/K2mgHL2hw9FyWNTIPXAZ1Gpdv9II4uYK1/71vY5/mIQS5cBP0o/Ogtf9TC@ux@MJ4NSosryvwC "Julia 1.0 – Try It Online")
I wish Julia had a `center` function
output is a list of lines
[Answer]
# [Kotlin](https://kotlinlang.org), 186 bytes
```
val p={n:Int->for(p in n downTo 1)for(l in n downTo 1)for(g in n-1 downTo 1-n)for(c in n-1 downTo 1-n)print(when{p+Math.abs(g)<=n&&l+Math.abs(c)<=n->'*'
g!=1-n||c!=1-n->' '
else->'\n'})}
```
[Try it online!](https://tio.run/##lVfNbuM2EL77KcY5JJJqy0iyKApjHaBdtEWALnJYH/dCS7QlRCYVklqvkfgB9kH6Yn2RdIak/mw5aYVAoocfPw6HMx@ZR2mKXLzOZnAvysrMQUiT5WIDa6nAZBxSvmZVYcBwbSBhmmuQaoR4JiAXhm@4ikf0@5PizPDUD8w1JDLlsJHFGpKMFQUXGz4nYGZMqeezGfVTd6wNSx75d0QhJE7kdvY0u7n9@ZfrG4IvVY72goNcg/FtbWf8M//GRccPEP/8@PtmAqVCA7AGjSPtvDzfZAYEEQUNE/3q9NiVacNVrh91OME2srv1fHmApwqjkEvhVvwHrlQs6gnn1kZP5BtR5FqR@6N2VD8dgtsTgvqJjgw1YdfQM0Xtq7UipH015qj/OHsEAy@3hi5Jny4693TW@OHsGt9a75trhzfiMNB7pj/qf4Ywdq3dzwDITtD/nKKGg9Tf0Lc@PeiJV@d9HHDurKvR@0@d3f/B457j73g84P@7jp8uI/q/j03IX0UKWgIWNnyRWw6qQmVoc/Uedio3HC5sDl9MYFWRvqwrkZAaEExxUylBwslAo7hgAxO/yFE0UWBQYlFpck3INbbBSBnX7EvF8oIG7DKcRJcsQcUSwFmS2YF@HEqo3PHUTY4qDQVnaX/YKeWqYOLRT88Ur0laIAmb1@opifHcL5WkX2dSkewTuFRyo9gW9rLCU0BMYMuZrhTqPcrjao8wp4m/fy@ZSOkY8MGBXW4y5N9uuTAIQjuRJVzrQFTbFVdzPHpMCM@jEYAXDJrddVL0SmZQkIXGID9VueITiOMYwXTSBL6T3PAjUrkTSwnXIRH2KP02@Nj6kTWb53MRP0fW0FmGjZJVabdatPwtn2e0qJZyet2QTp2l4e6zJ7KotsIdP9zNNekC01yXBdvbXjw7FUtwOTHcr@1x1UV6DzQIztPuEe1D0MXi7tXHt5u@O6oLtCBa8QRyo@kYrs/NuAtDd3bc5h7lrI0S4rxLfUbb4ab1nODTugN6QAq1y3U9LXq3s260KBv1NnpHYR915LbdgdZmazzoorDC8J7xPOqruY/dT5@ZyWK20m6fQ/i4GJ0eMz6bLi@tq@2YAahznHjqUdM7uIqujqAugONFswZ4eRlgq7exCyQ@OObjhea256u4gkM4OoCreipUW9mfGcayqerk5LZX3/FciW8RHWBRv35jBZSLZzHHIp/eITxwtdBWFtmKAdvG2nrlYu3JgN1tGu3Tc9nZkfDjQlxeFq0lIcv0jsK5GS9w5MtLYr9ow5BQELCFITiEh1ebb0u1R91xSkvZW2murnRz9YVPDC2Y/U688BbLSxsgUnAsJZSvdV5gsgrZ3FMnDouRk5U9HmSlQFdlSXKbgrLX4NFxtvu9wKynPoNuuYykAKfMMFhYP//C/ArC8Tg2EiMeuMwuA0KEXmEfROvnhKQZZSQXtvLrSdAjhz29/tPsB2yaJAu4UhL1e5kpuWOrgofeJ7sdhQgufmN0QOA/Fhg3iqCn0@OL2rGbsDeiNt@GdhrSGbV3yUgpNXr9Fw "Kotlin – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 19 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
·ÅÉεIL'*×.Bí€û×}˜.c
```
[Try it online](https://tio.run/##ASkA1v9vc2FiaWX//8K3w4XDic61SUwnKsOXLkLDreKCrMO7w5d9y5wuY///Mw) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5JlXUFpipaBkX6nDpeRfWgLh6VQeWvn/0PbDrYc7z209tM5HXevwdD2nw2sfNa05vPvw9NrTc/SS/@sc2mb/P9pIx1jHJBYA).
**Explanation:**
```
·                # Double the (implicit) input-integer
 ÅÉ              # Push a list of all odd numbers smaller than or equal to this 2*input
   ε             # Map over each odd integer:
    IL           #  Push a list in the range [1,input] again
      '*×       '#  Repeat "*" each integer amount of times as string
         .B      #  Box this list of strings, adding trailing spaces to make them all of
                 #  equal length
           í     #  Reverse each so the spaces are leading
            €û   #  Palindromize each string
              ×  #  Repeat each the current odd integer amount of times
   }˜            # After the map: flatten the list of lists
     .c          # Join this list of strings by newlines, and centralize it
                 # (after which it is output implicitly as result)
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 16 bytes
```
L'*×j.ºиøā·<×˜.C
```
[Try it online!](https://tio.run/##ASMA3P9vc2FiaWX//0wnKsOXai7CutC4w7jEgcK3PMOXy5wuQ///Mw "05AB1E – Try It Online")
```
L                -- range from 1 to n
 '*×             -- repeat "*" that many times
    j            -- pad to length n with spaces to the left
     .º          -- self-intersected mirror
       и         -- for each string, make a list of n copies
       ​ ø        -- transpose to get the rows of the big triangle
​​         ā       -- get the range from 1 to the number of rows (n)
          ​·<     -- double and decrement to get a list of the first n odd numbers
            ​×    -- repeat each string in the i-th row 2*i-1 times
             ​˜   -- flatten into a list of lines
              ​.C -- center and join by newlines
```
[Try it with step-by-step output!](https://tio.run/##dZE9TsNAEIV7TjFyE4iSSIEOQUXLJdbesbNhPWvtThSlg5oD0HAPEGVCR8MZuIiZdXAcW2Ea74/fN2/nuaBSg3V9D4NKvKICIfeuhDmwA7qGZHKbJJMzGI13L4OfsULFcjECXsiiVLQBNiWGTiW17IkqpSPYIhW8AIK1kU@oVIYhnvMC5S7nHgFm248jRECbTw0x@oAZo4bSeO98XwLw/d5JcucBVSad2BsqJuL1AUGBNYHB5eIjc5UZGJf6eXyG3YGTsMwnVC5gtFogN3a9W4fIiOvUFCAdZIoWDyyBRE5bn08t7kAYTD2e0apM0Uduwz@ni6G3vb3t280ept0qtfIm0qAx81gicWuze2hE58bLhsBp/dcmnGA39H3kbdJHEwRDDctMJT5xCJdjM52fSP@Y9vXaZGEVM5IQxF3nzBr6Txq1sztIMoyhN09cOjGQboBw3RPW9dUv)
]