0

What is the best algorithm for scaling a curve line made up of points? For example:

Curve line (A):
o               
 o             
  o            o o   
   o         o     o     o o
    o       o       o   o   o
     o     o         o o     o
       o o

If Curve Line (A) is scaled "Smaller" by 5% then it looks like this.

Output:

o
 o        o o
  o      o    o   o o
   o    o      o o   o
    o o

If Curve Line (A) is scaled "Bigger" by 10% then it looks like this.

o               
 o             
  o                
   o               
    o                o o    
     o             o     o      o o    
      o           o       o   o     o
       o         o         o o       o
        o       o
         o     o
           o o

I just want to know the algorithm, concept or the idea on how to solve it but to make it more clearer here are some java codes I want to achieved.

class CurveLine
{
    public static ArrayList<float[]> getScaledCurveLine
    (float[][] curveLine, float percentage, bool enlarged)
    {
         ArrayList<float[]> scaledCurveLine = new ArrayList<float[]>();
         /*
               Some Algorithm for Scaling Curve Line
         */
         return scaledCurveLine; //new set of points
    }

    public static void main (string args[])
    {
         float [][] curveLine = new float[20][2]; //set of points
         curveLine[0][0] = 0; //x1
         curveLine[0][1] = 5; //y1
         curveLine[1][0] = 1; //x2
         //and so on..

         ArrayList<float[]> largerCurveLine = getScaledCurveLine(curveLine, 20, true);
         ArrayList<float[]> smallerCurveLine = getScaledCurveLine(curveLine, 20, false);
    }
}

I read some algorithm such as "Nearest Neighbor Interpolation" in scaling points but I'm not sure if I'm on the right path :(.

I badly need to know how to do it guys :( thanks in advance.

Techreator
  • 83
  • 8
  • 1
    `point *= 0.95` or `point *= 1.1` - some language tag or code might make it possible to give a real answer. – Marco13 Nov 11 '17 at 11:45
  • thanks for the response @Marco13 .. I put some java code to make it clearer. Thanks. – Techreator Nov 11 '17 at 13:30
  • In your examples, the downscaled plot contains fewer points than the original, and the upscaled one more points. But you didn't specify the rules for that (e.g. scale the number of points by the same factor, keep them equidistant in x, ...?). Without such a rule, @Marco13's approach, keeping all the points and just moving them individually, is the easiest and most accurate solution I can imagine. – Ralf Kleberhoff Nov 11 '17 at 13:54
  • Yah the rules on how it will add some points when it gets bigger, remove some points when it is smaller, and move points according to there specified location when scaled is what Im trying to know. Dont you think there are some algorithms out there that can solve this problem where they already specify a rule for this? In Microsoft Powerpoint they already achieved the scaling of curve lines of points, I'm curious on how they do it lol. – Techreator Nov 11 '17 at 14:10
  • Regarding your example code: **This is not a curve**. It is a sequence of (straight) line segments. There are solutions for scaling curves, and eventually *converting* them to a sequence of straight line segments, with as many points as you wish. But first, this requires a *real curve* in the first place (e.g. a cubic- or bezier curve), and second, the maths behind that are a bit too complex to summarize it in an answer. (continued in next comment...) – Marco13 Nov 11 '17 at 20:02
  • Java already offers all the necessary classes for all this: If you describe your curve as a **real** curve, using e.g. the [`Path2D#curveTo`](https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Path2D.html#curveTo-double-double-double-double-double-double-) method, then you can scale it arbitrarily, and use a (flattening!) [`PathIterator`](https://docs.oracle.com/javase/8/docs/api/java/awt/geom/PathIterator.html) to obtain the scaled points. If this could be helpful for you, I could create an example and post it as an answer. – Marco13 Nov 11 '17 at 20:04

1 Answers1

0

If I get your question right You basically want resize your polyline (curve) without changing the point density.

  1. approximate/fit curve to match your polyline

    If you got many points than you should do this piecewise (using 4 point cubics for example). In case you got some original polyline data you could remember the original polyline as curve for any further resampling to avoid fitting on each resize.

    for more info see How can i produce multi point linear interpolation?

    The polynomial degree of the curve used depends on what continuity you need. For basic graphic stuff 4 point cubics are enough. But if you need that also higher derivates are smooth than you need to use higher degrees.

  2. multiply all curve control points by scale

    in case you are using curve defined by vectors multiply them too ... If you want to do more complex transformations or rescale differently in each axis than you should apply this step after sampling in bullet #3. Because those transformations will produced different results if done on control points and on the curve points itself.

  3. sample new polyline

    so simply iterate over your curve by the new point density (parameter step) and use produced points as your new polyline.

    In case you are applying transformation #2 in this step the parameter step will be affected by the scale too.

    In case of piecewise curves with parameter t=<0,1> you need to start with t for next curve with value from the last one. so once the t crosses 1.0 you are moving to next curve and should start with t-1.0 parameter start value.

    If you want more precise density than you need to find point on curve that is exact distance from the last one instead of constant parameter increment.

Here is a quick sketch of what I had in mind by all this:

sketch

Spektre
  • 49,595
  • 11
  • 110
  • 380