【问题标题】:Bézier curve map x,y points to screen贝塞尔曲线图 x,y 指向屏幕
【发布时间】:2016-07-10 17:24:44
【问题描述】:

嗨,最近我实现了贝塞尔曲线,它工作正常,但我的问题是我不知道如何将 x,y 点映射到屏幕,因为它以小数点的形式给了我 x,y,我将不胜感激 这是我认为有效的代码。

        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;
        }
    }

我使用生成的点在 excel 中绘制它们,这是我的结果

三次贝塞尔曲线初始 t=0,step = 0.01 的示例,带有控制点 (-5, 0),(0, 5),(5, 0),(0,-5) 生成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

生成的 Y 点

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

【问题讨论】:

  • 这看起来像是将 double 转换为 int 问题 -_- 吗??
  • "它工作正常,但我的问题是我不知道如何将 x,y 点映射到屏幕因为它以小数点的形式给了我 x,y",确实如此。
  • 老兄,我知道,但在这里你不能简单地将它转换为 int,必须有一种方法,当你这样做时,结果曲线是一样的,希望它现在清晰

标签: java math interpolation bezier


【解决方案1】:

将一组点乘以某个比例因子,然后四舍五入为整数。我建议 x 使用因子 Screen Width/MAX(list of x points),y 使用 Screen Height/MAX(list of y points)。这应该会给你一个缩放到当前屏幕大小的点列表。这是一些实现这个想法的python代码。

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);

这将返回以下 X 坐标列表:

[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]

这里是 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]

此脚本并不完美,并且不会返回正确范围内的值,但它应该让您知道从哪里开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多