skip to Main Content

Please tell me how I can build a circle point by point, making sure to move sequentially around the circle like the hand of a clock.

Now I can build a circle, but in my loop the points are placed in a random order and at the end I get a circle.

theta = 0, x = 16, y = 6
theta = 1, x = 11, y = 14
theta = 2, x = 2, y = 15
theta = 3, x = -4, y = 7
theta = 4, x = -1, y = -2
theta = 5, x = 9, y = -4

I need to build a circle sequentially, so that for example I can draw only half a circle or draw a circle with certain changing colors. I assume it’s all in radians, but we need to use degrees somehow. But I have no more ideas. Thanks.

$radius = 10;
$centerX = 6;
$centerY = 6;

$theta = 0;

$white = imagecolorallocate($im, 0, 255, 0);

while ($theta <= 360) {
    $x = round($centerX + $radius * cos($theta));
    $y = round($centerY + $radius * sin($theta));
    $theta += 1;

    imagesetpixel($im, $x, $y, $white);
}

I tried to use the deg2rad() function to somehow use degrees, but my knowledge of mathematics is not enough.

2

Answers


  1. You’re doing it almost correctly, you just need to use the imagecreate() function to create an image, and after the while loop use imagepng() to render the image, and don’t forget to use add a proper Content-Type header to render the image correctly in the browser.

    Here’s the modified code, I’ve made some changes:

    header('Content-type: image/png'); 
    
    $im = imagecreate(500, 500);
    
    $radius = 100;
    $centerX = 250;
    $centerY = 250;
    
    $theta = 0;
    
    $white = imagecolorallocate($im, 0, 255, 0); // use a background color for the image
    $black = imagecolorallocate($im, 0, 0, 0); // use a black color for the line
    
    while ($theta <= 360) {
        $x = round($centerX + $radius * cos($theta));
        $y = round($centerY + $radius * sin($theta));
        $theta += 1;
    
        imagesetpixel($im, $x, $y, $black); // draw the perimeter as dots
    }
    
    imagepng($im); // send the image to the browser
    

    You were using a line color that’s identical to the background color, so you wouldn’t have been able to see the circle. Here, I’ve used a different color.

    Here’s an image of the result:

    enter image description here

    Note: you could make $theta increase by smaller values (e.g. 0.5, 0.2, 0.1) to get a smoother look.

    Login or Signup to reply.
  2. I tried to use the deg2rad() function to somehow use degrees"

    You were close. Both cos() and sin() expect radians so that part should have been right. Alternatively, you can work directly in radians. Rather than looping from 0 to 360, loop from 0 to 2 * M_PI and make your increments smaller (e.g. M_PI / 100).

    Additionally:

    • imagecolorallocate() component order is RGB, so your $white was actually electric green.
    • Not a problem, but for is a bit more compact (readable?) that while for this use case.

    All together, with some polishing:

    $radius = 150;
    $step = M_PI / 100;
    $centerX = $centerY = $radius;
    
    $im = imagecreate(2 * $radius, 2 * $radius);
    $black = imagecolorallocate($im, 0, 0, 0);
    $white = imagecolorallocate($im, 255, 255, 255);
    
    for ($theta = 0; $theta < 2 * M_PI; $theta += $step) {
        $x = round($centerX + $radius * cos($theta));
        $y = round($centerY + $radius * sin($theta));
        imagesetpixel($im, $x, $y, $white);
    }
    
    imagepng($im, '/tmp/circle.png');
    

    Output:

    Rendered circl

    Degrees version:

    $radius = 150;
    $step = 1;
    $centerX = $centerY = $radius;
    
    $im = imagecreate(2 * $radius, 2 * $radius);
    $black = imagecolorallocate($im, 0, 0, 0);
    $white = imagecolorallocate($im, 255, 255, 255);
    
    for ($theta = 0; $theta < 360; $theta += $step) {
        $x = round($centerX + $radius * cos(deg2rad($theta)));
        $y = round($centerY + $radius * sin(deg2rad($theta)));
        imagesetpixel($im, $x, $y, $white);
    }
    
    imagepng($im, '/tmp/circle.png');
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search