Click here to Skip to main content
15,907,392 members
Articles / Programming Languages / C++
Article

Straight line function, optionally clamped

Rate me:
Please Sign up or sign in to vote.
2.65/5 (5 votes)
7 Oct 20042 min read 30.4K   286   12   1
A tiny template for a straight line function with values optionally clamped outside a range

Introduction

Sometimes you just need a simple straight line function, and that's what ClampedLine<class T> gives you. If you feel like getting fancy, you have the option of "clamping" Y to minimum and maximum values outside of a range in X, as shown in the brilliantly detailed picture above. The code is simple, as opposed to fast, and should compile just about anywhere. After you create a ClampedLine, the "function call" T operator()(T X) can be used to pull out a Y value for a particular X.

This certainly isn't original, but I couldn't find a free equivalent anywhere after a quick search.

Here are a couple of examples, rather than rambling on:

#include "clampedline.h"

// Fahrenheit to Celsius conversion.
ClampedLine<float> celsiusFromFahrenheit(32.0, 0, 212.0, 100.0, false);
float y = celsiusFromFahrenheit(72.0); // = 22.2 degrees Celsius

// Clipping and scaling a raw score to produce a "final" score:
// Scale raw 60..90 to final 10..100, 
// values below 60 give 10 and above 90 give 100.
ClampedLine<long>    adjustedScore(60, 10, 90, 100, true);
long finalScore = adjustedScore(-5); // finalScore = 10, the lowest possible
finalScore = adjustedScore(60);      // also gives finalScore = 10
finalScore = adjustedScore(75);      // finalScore = 55, halfway up
finalScore = adjustedScore(90);      // finalScore = 100, the highest possible
finalScore = adjustedScore(140);     // also gives finalScore = 100

Using the code

  1. Include the header file "clampedline.h". Note it doesn't include any other headers.
  2. You'll need two points (X0, Y0) (X1,Y1) on your line. If you specify a clamped line, then values of X below X0 will give a Y value of Y0, and values of X above X1 will return a Y value of Y1.
  3. A simple signed arithmetic type such as long or double works best as the "T" parameter for the template. If you try an unsigned type for T, watch out for values of X that give a nominally negative value of Y.
  4. If your ClampedLine lives a long time, you could package it cleanly in a member function, something like:
    long MyClass::FinalScore(long rawScore)
     {
      static ClampedLine<long>    adjustedScore(
        60, 10, 90, 100, true);
      return adjustedScore(rawScore);
     }
  5. The code isn't copyrighted. Scale, offset and clamp to your heart's content, specialize it, add getters and setters. In a brief fit of lucidity I tested this little class before zipping it, but you shouldn't take my word for that.

Points of Interest

When "T" is an integer type, results are rounded (see the code for the standard trick to do that). And you'll get values out without complaint if you have X0 equal to X1 in the constructor for your ClampedLine, just don't expect them to be the values you want:)

History

  • Version 1.0, Oct 7, 2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
Ken likes tennis, the piano, Buffy, and programming, in no particular order.

Comments and Discussions

 
QuestionUpdate? Pin
kenearle7-Aug-07 12:51
kenearle7-Aug-07 12:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.