Using Maths to print patterns

Hello There, I need your expert advice on a tricky programming related question. How to use maths functions to print a particular pattern such as diamond or a heart shape. I need to print the shape using "*" and " ". If you would print a heart shape pattern using only "*" and " " , what approach you would apply ?
> If you would print a heart shape pattern using only "*" and " " , what approach you would apply ?

1. Determine the equation for the mathematical curve that will produce the shape.

2. Using the equation, calculate the points that form the curve.

3. Transpose and scale to an NxN integer cartsian co-ordinate system, where x and y are in the range [0,N)

4. Print out the curve by placing a * for each x,y co-ordiate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <string>
#include <cmath>
#include <utility>
#include <vector>
#include <set>

using canvas_type = std::vector<std::string> ;
using point_type = std::pair<double,double> ;
using xy_pos_type = std::pair<int,int> ;

// determine the points that form a heart shape 
// for instance: from the paremetic equation
//               x = sin(t) * cost(t) * ln (abs(t) )
//               y = pow( abs(t), 0.3 ) * sqrt( cos(t) )
//               for t in [-1, +1 ]
std::set<point_type> make_heart( double delta = 0.001 )
{
    std::set<point_type> points ;

    for( double t = -1.0 + delta ; t < +1.0 - delta ; t += delta )
    {
        const double x = std::sin(t) * std::cos(t) * std::log( std::abs(t) ) ;
        const double y = std::pow( std::abs(t), 0.3 ) * std::sqrt( std::cos(t) ) ;
        points.emplace(x,y) ;
    }

    return points ;
}

// normalize the x values so that min x == 0
// scale to integers in an N * N grid
// invert the y values (in our grid, y increases downwards)
std::set<xy_pos_type> normalize( std::set<point_type> points, std::size_t N )
{
    std::set<xy_pos_type> result ;
    const double minx = points.begin()->first ;

    for( auto& pt : points )
    {
        int ix = std::lround( ( pt.first + ( 0 - minx ) ) * N ) ;
        int iy = std::lround( pt.second * N ) ;
        iy = N - iy - 1 ;
        result.emplace( ix, iy ) ;
    }

    return result ;
}

int main()
{
    constexpr int N = 100 ;
    
    // get the normalized x, y co-ordinates
    const auto points = normalize( make_heart(), N ) ;
    
    // create a grid filled with spaces
    const std::string blanks( N, ' ' ) ;
    canvas_type canvas( N, blanks ) ;
    
    // place a * at each point that is a part of the curve 
    for( auto& pt : points ) canvas[pt.second][pt.first] = '*' ;
    
    // print the grid
    std::cout << "Heart:\n" ;
    for( const std::string& str : canvas )
        if( str != blanks ) std::cout << str << '\n' ;
}

http://coliru.stacked-crooked.com/a/2f3f79a05bc42867
thank you brother you solved my problem. :) You gave me the clear Idea. :)
Topic archived. No new replies allowed.