Aram Rafeq
Aram Rafeq

Reputation: 41

Bézier curve map x,y points to screen

hi recently i implemented the bezier curve it works fine but my problem is i dont know how to map x,y points to the screen because it gives me x,y in form of decimal points i will appreciate any help this is my code which works i think .

        import java.util.ArrayList;


    public class Bezier {

        public static void main(String[] args) {
            ArrayList<Point> CP = new ArrayList<Point>();
            CP.add(new Point(-5, 0));
            CP.add(new Point(0, 5));
            CP.add(new Point(5, 0));
            CP.add(new Point(0,-5));


            Bezier curve = new Bezier(3, 0, 0.01, CP);
            curve.DefineBezierCurve();

            ArrayList<Point>Results = curve.getCurvePoints();

            for(int i = 0; i<Results.size() ; i++){
                Point x = Results.get(i);
                System.out.println(x.Y);
            }


        }
    //  class definitions
        private ArrayList<Point> controlPoints;// the control points
        private double t;//the value of t indicates the location of the point on the line sigment
        private double step;// the increment value that the t increments
        private int N;//the Beziar Curve Order
        private ArrayList<Point>CurvePoints;// genrated (x,y) values of the curve

    // constructor
        public Bezier(int n , double t , double step ,ArrayList<Point> CP ){
            this.N = n ;
            this.t = t;
            this.step = step;
            this.controlPoints = CP;
            CurvePoints = new ArrayList<Point>();
        }

        private int factorial(int x){
            int result =1;
            for(int i= x ; x>0 ; x--){
                result*=x;
            }
            return result;
        }
        private int BinomialCoefficient(int i){
            // we get the order form the global variable
            int factN = factorial(this.N);
            int factI = factorial(i);
            int factN_I = factorial(this.N-i);
            int theCoefficient = (factN/(factI*factN_I));
            return  theCoefficient ;
        }
        private Point BI_N_P(int i){
            int coefficient = BinomialCoefficient(i);
            Point CurrentControlPoint = this.controlPoints.get(i);
            double X = coefficient* Math.pow(t,i)* Math.pow((1-t),(this.N-i))*CurrentControlPoint.X ;
            double Y = coefficient* Math.pow(t,i)* Math.pow((1-t),(this.N-i))*CurrentControlPoint.Y ;
            Point Tmp  = new Point(X, Y);
            return Tmp;
    //      this.CurvePoints.add(PointOnCrve);
        }
        private void DefineBezierCurve(){
            while(t<=1){
                Point PointOnCurve = new Point(0, 0);
                for(int i = 0 ; i<=this.N ; i++){
                    Point tmp = BI_N_P(i);
                    PointOnCurve.X+=tmp.X;
                    PointOnCurve.Y+=tmp.Y;
                }
                this.CurvePoints.add(PointOnCurve);
                this.t+=this.step;
            }
        }

        public ArrayList<Point> getCurvePoints(){
            return this.CurvePoints;
        }

    }
    class Point{    
        public double X;
        public double Y;
        public Point(double x,double y){
            X=x;
            Y=y;
        }
    }

i used the genrated points to draw them in excel and this was my result enter image description here

example of cubic bezier curve initial t=0,step = 0.01 , with control points (-5, 0),(0, 5),(5, 0),(0,-5) generated X points

-5.0
-4.85001
-4.700079999999999
-4.55027
-4.400639999999999
-4.25125
-4.102159999999999
-3.9534299999999996
-3.80512
-3.6572900000000006
-3.5100000000000007
-3.3633100000000002
-3.2172800000000006
-3.07197
-2.92744
-2.7837499999999995
-2.6409599999999993
-2.4991299999999996
-2.3583199999999995
-2.2185899999999994
-2.0799999999999996
-1.9426099999999988
-1.8064799999999992
-1.6716699999999989
-1.5382399999999987
-1.4062499999999998
-1.2757599999999993
-1.1468299999999993
-1.0195199999999995
-0.8938899999999995
-0.7699999999999991
-0.6479099999999991
-0.527679999999999
-0.4093699999999989
-0.29303999999999886
-0.17874999999999885
-0.06655999999999862
0.043470000000001674
0.15128000000000164
0.256810000000002
0.3600000000000019
0.4607900000000018
0.5591200000000022
0.6549300000000019
0.7481600000000019
0.838750000000002
0.9266400000000021
1.011770000000002
1.094080000000002
1.173510000000002
1.2500000000000018
1.3234900000000016
1.3939200000000018
1.4612300000000018
1.5253600000000018
1.5862500000000017
1.6438400000000017
1.6980700000000017
1.7488800000000018
1.7962100000000016
1.8400000000000019
1.8801900000000014
1.916720000000001
1.9495300000000007
1.9785600000000012
2.0037500000000006
2.0250400000000006
2.042370000000001
2.05568
2.0649100000000002
2.0700000000000003
2.07089
2.06752
2.0598299999999994
2.0477599999999994
2.031249999999999
2.010239999999999
1.984669999999999
1.9544799999999984
1.9196099999999983
1.8799999999999981
1.8355899999999976
1.7863199999999972
1.7321299999999973
1.672959999999997
1.6087499999999963
1.539439999999996
1.4649699999999957
1.3852799999999954
1.3003099999999952
1.2099999999999946
1.1142899999999942
1.0131199999999938
0.9064299999999934
0.7941599999999929
0.6762499999999925
0.552639999999992
0.4232699999999916
0.28807999999999107
0.14700999999999054

generated Y points

0.0
0.14701
0.28808
0.42327
0.55264
0.6762500000000001
0.79416
0.90643
1.0131200000000002
1.1142900000000002
1.21
1.3003099999999999
1.3852799999999996
1.4649699999999997
1.5394399999999997
1.6087499999999997
1.6729599999999996
1.7321299999999997
1.78632
1.83559
1.88
1.91961
1.95448
1.98467
2.0102400000000005
2.0312500000000004
2.0477600000000002
2.0598300000000003
2.0675200000000005
2.0708900000000003
2.0700000000000003
2.0649100000000002
2.0556800000000006
2.0423700000000005
2.0250400000000006
2.00375
1.9785599999999997
1.9495300000000002
1.91672
1.8801899999999998
1.8399999999999999
1.7962099999999999
1.748879999999999
1.6980699999999993
1.6438399999999993
1.5862499999999993
1.5253599999999992
1.461229999999999
1.3939199999999987
1.3234899999999983
1.2499999999999982
1.173509999999998
1.094079999999998
1.011769999999998
0.9266399999999977
0.8387499999999977
0.7481599999999973
0.6549299999999975
0.5591199999999971
0.46078999999999715
0.359999999999997
0.2568099999999969
0.15127999999999653
0.043469999999996345
-0.06656000000000395
-0.17875000000000396
-0.2930400000000042
-0.40937000000000445
-0.5276800000000048
-0.6479100000000048
-0.7700000000000049
-0.8938900000000052
-1.0195200000000053
-1.1468300000000053
-1.2757600000000053
-1.4062500000000062
-1.538240000000006
-1.6716700000000062
-1.8064800000000063
-1.9426100000000066
-2.0800000000000067
-2.218590000000007
-2.3583200000000066
-2.499130000000007
-2.6409600000000077
-2.783750000000008
-2.927440000000008
-3.0719700000000083
-3.217280000000008
-3.363310000000008
-3.5100000000000087
-3.6572900000000086
-3.805120000000009
-3.9534300000000084
-4.102160000000009
-4.251250000000009
-4.40064000000001
-4.550270000000009
-4.7000800000000105
-4.85001000000001

Upvotes: 0

Views: 563

Answers (1)

James Paterson
James Paterson

Reputation: 2915

Multiply the set of points by some scale factor, then round to an integer. I would suggest the factor Screen Width/MAX(list of x points) for x, and Screen Height/MAX(list of y points) for y. This should give you a list of points scaled to the current size of the screen. Here's some python code that implements the idea.

X = "-5.0 -4.85001 -4.700079999999999 -4.55027 -4.400639999999999 -4.25125 -4.102159999999999 -3.9534299999999996 -3.80512 -3.6572900000000006 -3.5100000000000007 -3.3633100000000002 -3.2172800000000006 -3.07197 -2.92744 -2.7837499999999995 -2.6409599999999993 -2.4991299999999996 -2.3583199999999995 -2.2185899999999994 -2.0799999999999996 -1.9426099999999988 -1.8064799999999992 -1.6716699999999989 -1.5382399999999987 -1.4062499999999998 -1.2757599999999993 -1.1468299999999993 -1.0195199999999995 -0.8938899999999995 -0.7699999999999991 -0.6479099999999991 -0.527679999999999 -0.4093699999999989 -0.29303999999999886 -0.17874999999999885 -0.06655999999999862 0.043470000000001674 0.15128000000000164 0.256810000000002 0.3600000000000019 0.4607900000000018 0.5591200000000022 0.6549300000000019 0.7481600000000019 0.838750000000002 0.9266400000000021 1.011770000000002 1.094080000000002 1.173510000000002 1.2500000000000018 1.3234900000000016 1.3939200000000018 1.4612300000000018 1.5253600000000018 1.5862500000000017 1.6438400000000017 1.6980700000000017 1.7488800000000018 1.7962100000000016 1.8400000000000019 1.8801900000000014 1.916720000000001 1.9495300000000007 1.9785600000000012 2.0037500000000006 2.0250400000000006 2.042370000000001 2.05568 2.0649100000000002 2.0700000000000003 2.07089 2.06752 2.0598299999999994 2.0477599999999994 2.031249999999999 2.010239999999999 1.984669999999999 1.9544799999999984 1.9196099999999983 1.8799999999999981 1.8355899999999976 1.7863199999999972 1.7321299999999973 1.672959999999997 1.6087499999999963 1.539439999999996 1.4649699999999957 1.3852799999999954 1.3003099999999952 1.2099999999999946 1.1142899999999942 1.0131199999999938 0.9064299999999934 0.7941599999999929 0.6762499999999925 0.552639999999992 0.4232699999999916 0.28807999999999107 0.14700999999999054"
X = X.split(" ");
absX = list();
for x in X:
    absX.append(abs(float(x)));
max_X = max(absX);
min_X = min(X);
screen_width = 1024;
scale_factor = screen_width/float(max_X + float(max(X)));
newX = list();
for x in X:
    x = int(float(x)*scale_factor) + screen_width;
    newX.append(x)
print(newX);

This returns the following list of X coordinates:

[300, 322, 344, 366, 387, 409, 430, 452, 473, 495, 516, 537, 559, 580, 601, 621, 642, 663, 683, 703, 723, 743, 763, 782, 802, 821, 840, 858, 877, 895, 913, 931, 948, 965, 982, 999, 1015, 1030, 1045, 1061, 1076, 1090, 1104, 1118, 1132, 1145, 1158, 1170, 1182, 1193, 1205, 1215, 1225, 1235, 1244, 1253, 1262, 1269, 1277, 1284, 1290, 1296, 1301, 1306, 1310, 1314, 1317, 1319, 1321, 1323, 1323, 1323, 1323, 1322, 1320, 1318, 1315, 1311, 1307, 1301, 1296, 1289, 1282, 1274, 1266, 1256, 1246, 1236, 1224, 1212, 1199, 1185, 1170, 1155, 1139, 1121, 1104, 1085, 1065, 1045]

And here's the Y:

[768, 784, 799, 814, 829, 843, 856, 868, 880, 891, 902, 912, 921, 930, 938, 946, 953, 960, 966, 971, 976, 981, 984, 988, 991, 993, 995, 996, 997, 997, 997, 997, 996, 994, 992, 990, 987, 984, 980, 976, 972, 967, 962, 956, 950, 944, 937, 930, 922, 914, 906, 898, 889, 880, 870, 861, 851, 840, 830, 819, 807, 796, 784, 772, 761, 749, 736, 723, 710, 697, 683, 669, 655, 641, 627, 612, 598, 583, 568, 553, 538, 522, 507, 491, 475, 460, 444, 428, 411, 395, 379, 363, 346, 330, 313, 297, 280, 264, 247, 230]

This script isn't perfect and doesn't return values within the correct range, but it should give you an idea as of where to start.

Upvotes: 1

Related Questions