-1

I want to write a C program that produces 1000x1000 .ppm file, showing a vertical gradient from black(left) to white (right). Now, if the picture would be 256x256 it would be easy:

P3
256 256
255
0 0 0 1 1 1 2 2 2 .... 255 255 255
0 0 0 1 1 1 2 2 2 .... 255 255 255
.
.
.
0 0 0 1 1 1 2 2 2 .... 255 255 255

Thing is, since it must be 1000x1000 (exceeding 255), I'm not sure what formula I should follow to get a perfect gradient. Any ideas?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Andrei0408
  • 197
  • 7

1 Answers1

1

You can scale the pixel's color index by the total desired width to generate a decimal between 0 and 1 that represents its normalized position within the line. Then multiply by 256 to scale it to the color range. This gives:

int color = (float)offset / width * 256;

Runnable proof of concept:

const makeGradient = (gradEl, width=500, height=500) => {
  let html = "";
  
  for (let offset = 0; offset < width; offset++) {
    const color = offset / width * 256; // JS does float division
    html += `
      <div style="
        background-color: rgb(${color}, ${color}, ${color});
        width: 1px; height: ${height}px;
      "></div>
    `;
  }
  
  gradEl.innerHTML = html;
};

const gradEl = document.querySelector("#gradient");
makeGradient(gradEl);
document.querySelector("input")
  .addEventListener("keyup", e => {
    makeGradient(gradEl, +e.target.value || null);
  });
body {
  background: blue;
}

#gradient {
  display: flex;
}
<input value="500" type="number" min="0" max="2000">
<div id="gradient"></div>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 1
    First of all, this is no coding service. Futhermore, this is apparently not C the question is tagged. Please refrain from answering such questions. You have enough reps to help moderating this site, so please help close such questions according to site rules. – too honest for this site Mar 06 '21 at 21:38
  • @toohonestforthissite I do quite a bit of closing (feel free to check my stats) and I don't disagree with your fundamental premise, but for a formula like this it's pretty hard to show an attempt beyond OP's reasoning--they've clearly thought about it a bit and shared their thought process. C doesn't run in the browser or do visuals well, so JS is used purely to interactively show that the C formula I gave works. If I gave the whole C code to generate PPMs, that'd take the fun away from OP and isn't what they're looking for--they just want the formula for a gradient. – ggorlen Mar 06 '21 at 21:55
  • Ok, that's a viewpoint. You are right, that is not even related to the C language at all. It's just a simple math problem. However, I don't see any research about the formula from OP in the question. – too honest for this site Mar 06 '21 at 22:06
  • It is to the extent that integer division should be considered in C, and it's good that they provided the right amount of concrete context to avoid an XY problem. I'm not sure what I'd search or research on this exactly--I'm certain the answer is out there somewhere but I didn't see it obviously. DDG "stackoverflow gradient formula" gives this post. – ggorlen Mar 06 '21 at 22:10
  • The most simple solution is to do the math using fractional arithmetic with integers. This is more a matter of intepretation of values, so it boils down to integer arithmetic. The approach is similar to alpha-blending or e.g. breesenham line-drawing algorithm and many other graphic-algorithms (including 3D). These are (these days) often implemented in hardware using integers as floats are simply unnecessary. – too honest for this site Mar 06 '21 at 22:23
  • Feel free to add an answer, I'd be happy to learn a better approach. – ggorlen Mar 06 '21 at 22:51
  • 1
    @toohonestforthissite Okay so, I didn't add the code that I've already written because it was just writing in a file what I displayed in my post. I didn't need help with the *code*, I just needed the formula, that's all. If you feel like my post should be deleted feel free to do so. Edit: Also, the code is written in html and I'm writing a C program so no one gave me any 'code service', anyway – Andrei0408 Mar 07 '21 at 15:45
  • @Andrei0408: I got that already from the previous discussion. I understand you have a problem with the formula, but my opinion stays this is not really a programming, but a common basic math problem (let aside my discussion with ggorlen about int vs. float) about scaling. Oh, and just that wrong information doesn't stick: the code in the answer is JavaScript, not html. (read the comments if you don't trust me). – too honest for this site Mar 07 '21 at 15:53
  • @toohonestforthissite This just further proves that I don't need the actual code because I don't know JavaScript/html. Anyway, I'll delete the post later probably – Andrei0408 Mar 07 '21 at 15:55
  • @Andrei0408 I don't see the benefit in deleting this. This is a concrete, specific, reasonably common (how to scale numbers happens a lot in programming) and answerable programming problem. You've shown effort and given context and I don't see any obvious dupe. "too honest for this site" offers an alternative solution that I think would add value and should be posted as an answer. I voted to reopen. – ggorlen Mar 07 '21 at 18:20
  • The JS is literally just to create a playground for illustration. It's funny that using code to create an interactive visual is taken so critically by people who presumably use code to solve problems. The language the visualizer happens to be in is largely beside the point--`int color = (float)offset / width * 256;` is the actual C answer OP can use. The C tag is appropriate because writing mathematical expressions is language-specific. – ggorlen Mar 07 '21 at 18:27