android倒车动态辅助线自定义view

it2022-05-05  108

package com.skypine.df.ui.backcar;

import java.util.ArrayList; import java.util.List;

import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View;

public class ReverseCarTrackView extends View {     /**      * 杞ㄨ抗绾块鑹�      */     private static final int colorTrack = 0xFFe88b4c;     /**      * 鍩哄噯绾块鑹�      */     private static final int midColor = 0xFF008b4c;     private Install_ParameterTdef param = new Install_ParameterTdef();     private static List<XYpoint> xylistLeft = new ArrayList<XYpoint>();     private static List<XYpoint> xylistRight = new ArrayList<XYpoint>();

    private static double PI = ((double) 3.1415926535897);     private static int Video_N = 0;     private static int Video_P = 1;     private static int Video_MAX = 2;

    private int Distance = 500;// 鍙幇瀹炵殑璺濈鍗曚綅cm     private int Num = 51;     private int mAngel = 25;     private int mCalibration = 0;     private boolean mCaliTrackShow = false;     private static Paint revFlagColor = new Paint();     private static Paint revTrackColor = new Paint();     private static Paint revMidColor = new Paint();

    private int mFlagWidth = 40;// 鍗曚綅cm     private double[] mFlagScale = { 1, 0.8, 0.64, 0.512, 0.4, 0.32 };// 鍗曚綅cm     // 妯嚎涓暟     private int pointCount = (Num - 1) / (Distance / 100);     private int mtotalPoint = (Distance / 100) + 1;     public static int mScreenYBias = 28;// 杞ㄨ抗鏄剧ず鍦ㄥ睆骞曚笂鐨刌杞村亸绉�

    public static final int LEVEL_DATA_LEFT = -10;// 瀵逛簬涓績杞寸殑鍋忕Щ璺濈锛屽崟浣峜m     public static final int LEVEL_DATA_MIDDLE = 0;     public static final int LEVEL_DATA_RIGHT = 10;

    public static final int ANGLE_MIN_VALUE = -40;     public static final int ANGLE_MAX_VALUE = 40;

    public ReverseCarTrackView(Context context)     {         super(context);         initData();         initPaint();     }

    public ReverseCarTrackView(Context context, AttributeSet attrs)     {         super(context, attrs);         TypedArray typeArray = context.obtainStyledAttributes(attrs,                 R.styleable.ReverseTrack);         mAngel = typeArray.getInt(R.styleable.ReverseTrack_wheelangle, mAngel);         mCalibration = typeArray.getInt(                 R.styleable.ReverseTrack_wheelcalibration, mCalibration);         mCaliTrackShow = typeArray.getBoolean(                 R.styleable.ReverseTrack_wheelshowtrack, mCaliTrackShow);         typeArray.recycle();         initData();         initPaint();     }

    @Override     protected void onDraw(Canvas canvas)     {         super.onDraw(canvas);         canvas.save();         boolean bHardware = canvas.isHardwareAccelerated();         if (bHardware)         {             setLayerType(View.LAYER_TYPE_SOFTWARE, null);         }         onDrawUIFinal(canvas);         canvas.restore();     }

    private void onDrawUIFinal(Canvas canvas)     {         GetXYListFinal(Distance, Num, mAngel, param, canvas);     }

    /**      * 鍒濆鍖栫敾绗旈鑹�      */     private void initPaint()     {         revFlagColor.setColor(colorTrack);         revFlagColor.setStrokeWidth(4);         revFlagColor.setAntiAlias(true);

        revTrackColor.setColor(colorTrack);         revTrackColor.setStrokeWidth(6);         revTrackColor.setAntiAlias(true);

        revMidColor.setColor(midColor);         revMidColor.setStrokeWidth(4);         revMidColor.setAntiAlias(true);     }

    public class XYpoint     {         public double x;         public double y;         boolean valid; // 鍧愭爣鐐规棤鏁堬紝鏃犳硶灏嗗疄闄呭湴闈㈠潗鏍囦笂鐨剎y鎶曞奖鍒板睆骞曞潗鏍囦笂鐨刋Y     }

    public class Install_ParameterTdef     {         int sH; // 灞忓箷鍍忕礌鐐归珮搴�         int sW; // 灞忓箷鍍忕礌鐐瑰搴�         int format; // 鎽勫儚澶村埗寮�         double fu; // 鎽勫儚澶磋璺濇瘮瑙嗛珮锛岃繖涓�奸渶瑕佸畨瑁呮椂鏍囧畾         double camera_high; // 鎽勫儚澶村畨瑁呰窛鍦伴潰楂樺害锛屽崟浣嶅帢绫�         double camera_high_h; // 鎽勫儚澶村畨瑁呰窛杞﹀熬涓婅竟楂樺害锛屽崟浣嶅帢绫�         double camera_angle; // 鎽勫儚澶村畨瑁呰搴︼紝0~360搴︼紝涓嶆槸0~3.14         double L; // 杞﹁締鍓嶅悗杞窛锛屽崟浣嶅帢绫�         double D; // 鎽勫儚澶村畨瑁呯偣锛屼笌鍚庤疆杞磋繛绾匡紝鍦ㄥ湴闈㈡姇褰卞悗锛岀殑鍨傜洿璺濈锛屽崟浣嶅帢绫�         double d; // 鎽勫儚澶村畨瑁呯偣锛屼笌鍚庤疆杞磋繛绾夸腑鍨傜嚎锛屽湪鍦伴潰鎶曞奖鍚庯紝鐨勫瀭鐩磋窛绂伙紝鍗曚綅鍘樼背         double W; // 杞﹁締鍚庤疆闂磋窛绂伙紝鍗曚綅鍘樼背     }

    public Install_ParameterTdef initData()     {         // 480         param.sH = 800;         param.sW = 1024;         param.format = Video_P;         param.fu = 0.40;         param.camera_high = 59.0;         param.camera_high_h = 10.0;         param.camera_angle = 50;// 80搴�         param.L = 270.0;         param.D = 60.0;         param.d = mCalibration;// -30.0;锛屾牎鍑嗗弬鏁�         param.W = 150.0;         return param;     }

    /**      * 璁剧疆鏂瑰悜鐩樿浆鍚戣瑙掑害锛屽崟浣峚ngle      *      * @param angel      */     public void setCarAngle(int angel)     {         this.mAngel = angel;     }

    /**      * 璁剧疆鏍″噯璺濈锛屽崟浣峜m      *      * @param level      */     public void setCalibrationLevel(int level)     {         this.param.d = level;     }

    public void drawarcLine(Canvas canvas, List<XYpoint> listXYpoint)     {         canvas.save();         if (listXYpoint != null)         {             for (int i = 0; i < listXYpoint.size() - 1; i++)             {                 if (listXYpoint.get(i).valid)                 {                     canvas.drawLine((float) listXYpoint.get(i).x,                             (float) listXYpoint.get(i).y,                             (float) listXYpoint.get(i + 1).x,                             (float) listXYpoint.get(i + 1).y, revTrackColor);                 }             }         }         canvas.restore();     }

    /**      * 鏈�鍚庣殑鍑犳牴绾夸笉鐢诲嚭鏉�      *      * @param canvas      */     public void drawarcLine2(Canvas canvas, List<XYpoint> listXYpoint)     {         if (listXYpoint != null)         {             int aa = (int) (((-mAngel - 30) / 30.0) * listXYpoint.size());             if (aa <= 0)                 aa = 0;             for (int i = 0; i < listXYpoint.size() - 1 - aa; i++)             {                 canvas.drawLine((float) listXYpoint.get(i).x,                         (float) listXYpoint.get(i).y,                         (float) listXYpoint.get(i + 1).x,                         (float) listXYpoint.get(i + 1).y, revTrackColor);             }         }     }

    /**      * 鏍规嵁璁$畻鍑虹殑宸﹀彸杞ㄨ抗绾胯绠楄窛绂绘爣蹇楃偣锛岃窛绂绘爣蹇楃偣鍏�5涓�      *      * @param canvas      */     private void drawFlagLine(Canvas canvas)     {         canvas.save();         if (xylistLeft != null && xylistRight != null)         {             for (int i = 0; i < xylistLeft.size(); i++)             {                 boolean validPoint = ((i % pointCount) == 0);                 if (validPoint && (i != 0))                 {                     double angle = Math.atan((xylistRight.get(i).y - xylistLeft                             .get(i).y)                             / (xylistRight.get(i).x - xylistLeft.get(i).x));                     float flagLeftX = (float) ((float) xylistLeft.get(i).x + Math                             .cos(angle)                             * (mFlagWidth * mFlagScale[i / pointCount]));                     float flagLeftY = (float) ((float) xylistLeft.get(i).y + Math                             .sin(angle)                             * (mFlagWidth * mFlagScale[i / pointCount]));                     canvas.drawLine((float) xylistLeft.get(i).x,                             (float) xylistLeft.get(i).y, flagLeftX, flagLeftY,                             revFlagColor);                     float flagRightX = (float) ((float) xylistRight.get(i).x - Math                             .cos(angle)                             * (mFlagWidth * mFlagScale[i / pointCount]));                     float flagRightY = (float) ((float) xylistRight.get(i).y - Math                             .sin(angle)                             * (mFlagWidth * mFlagScale[i / pointCount]));                     canvas.drawLine((float) xylistRight.get(i).x,                             (float) xylistRight.get(i).y, flagRightX,                             flagRightY, revFlagColor);                 }             }         }         canvas.restore();     }

    /**      * 鏍规嵁璁$畻鍑虹殑宸﹀彸杞ㄨ抗绾胯绠楀嚭鍩哄噯绾匡紝宸﹀彸鍩哄噯鐐瑰悇5涓�      *      * @param canvas      */     private void drawFlagMiddleLine(Canvas canvas)     {         canvas.save();         if (xylistLeft != null && xylistRight != null)         {             for (int i = 0; i < xylistLeft.size(); i++)             {                 boolean validPoint = ((i % pointCount) == 0);                 if (validPoint && (i != 0))                 {                     canvas.drawLine((float) xylistLeft.get(i).x,                             (float) xylistLeft.get(i).y,                             (float) xylistRight.get(i).x,                             (float) xylistRight.get(i).y, revMidColor);                 }             }             int firstSpot = 0;             int lastSpot = xylistLeft.size() - 1;             canvas.drawLine((float) xylistLeft.get(firstSpot).x,                     (float) xylistLeft.get(firstSpot).y,                     (float) xylistLeft.get(lastSpot).x,                     (float) xylistLeft.get(lastSpot).y, revMidColor);             canvas.drawLine((float) xylistRight.get(firstSpot).x,                     (float) xylistRight.get(firstSpot).y,                     (float) xylistRight.get(lastSpot).x,                     (float) xylistRight.get(lastSpot).y, revMidColor);         }         canvas.restore();     }

    public boolean GetXYListFinal(double distance, int num, double angle,             Install_ParameterTdef param, Canvas canvas)     {         double camW;         double camH;         double L = param.L;         double W = param.W;         double D = param.D;         double d_ex = param.d;

        double R;         double anglePi;         int l_ex = 1;

        if ((xylistLeft == null) || (xylistRight == null) || (distance <= 0)                 || (num <= 0) || (Math.abs(angle) >= 90) || (param.sW <= 0)                 || (param.sH <= 0) || (param.format >= Video_MAX)                 || (param.format < Video_N) || (param.fu <= 0)                 || (param.L <= 0) || (param.W <= 0))         {             return false;         }         if (param.format == Video_N)         {

            camW = 720;             camH = 480;         }         else         {             camW = 720;             camH = 576;         }

        xylistLeft.clear();         xylistRight.clear();

        if (angle != 0)         {             if (angle < 0)             {                 l_ex = -1;             }

            anglePi = Math.abs(angle) / 180.0 * PI;             R = L / Math.tan(anglePi);

            for (int i = 0; i < num; i++)             {                 XYpoint xyTemp = new XYpoint();                 XYpoint xyTempY = new XYpoint();                 double tmp = Math.cos(distance * i / R / num);                 xyTemp.x = l_ex                         * ((R - l_ex * W / 2) * tmp - (R + l_ex * d_ex));                 xyTemp.y = Math.sqrt(Math.abs((R - l_ex * W / 2)                         * (R - l_ex * W / 2) - (xyTemp.x + l_ex * R + d_ex)                         * (xyTemp.x + l_ex * R + d_ex)))                         - D;

                xyTemp.x = xyTemp.x - l_ex * D                         * Math.sin(distance * i / R / num);                 xyTemp.y = (xyTemp.y + D * Math.cos(distance * i / R / num))                         + mScreenYBias;

                XYpoint temp = xyTemp;                 xylistLeft.add(i, xyTemp);

                xyTempY.x = l_ex                         * ((R + l_ex * W / 2) * tmp - (R + l_ex * d_ex));                 xyTempY.y = Math.sqrt(Math.abs((R + l_ex * W / 2)                         * (R + l_ex * W / 2) - (xyTempY.x + l_ex * R + d_ex)                         * (xyTempY.x + l_ex * R + d_ex)))                         - D;                 xyTempY.x = xyTempY.x - l_ex * D                         * Math.sin(distance * i / R / num);                 xyTempY.y = (xyTempY.y + D * Math.cos(distance * i / R / num))                         + mScreenYBias;                 xylistRight.add(i, xyTempY);             }         }         else         {             for (int i = 0; i < num; i++)             {                 XYpoint xyTemp = new XYpoint();                 XYpoint xyTempY = new XYpoint();                 xyTemp.x = 0.0 - W / 2.0 - d_ex;                 xyTemp.y = (distance * i / (double) num) + mScreenYBias;                 xylistLeft.add(i, xyTemp);

                xyTempY.x = W / 2.0 - d_ex;                 xyTempY.y = (distance * i / (double) num) + mScreenYBias;                 xylistRight.add(i, xyTempY);             }         }

        double bet;         double anglePi2;         int l = 1;         double camera_high = param.camera_high;         double camera_angle = param.camera_angle;         double fu = param.fu;         double screenH = param.sH;         double screenW = param.sW;

        if (camera_high < 0)         {             l = -1;         }         else if (camera_high == 0)         {             camera_high = 0.0000001;         }

        anglePi2 = camera_angle / 180.0 * PI;

        for (int i = 0; i < num; i++)         {             XYpoint xyTemp = new XYpoint();             xyTemp.x = xylistLeft.get(i).x;             bet = Math.atan(xylistLeft.get(i).y / camera_high);             if (camera_high < 0)             {                 bet = bet + PI;             }             if (((((anglePi2 - bet) * l) < (PI / 2)) && (((anglePi2 - bet) * l) > (0 - PI / 2)))                     || ((((anglePi2 - bet) * l) > (PI * 3 / 2)) && (((anglePi2 - bet) * l) < (PI * 5 / 2))))             {                 xylistLeft.get(i).y = screenH * camW * fu                         * Math.tan(anglePi2 - bet) / camH + screenH / 2;                 xylistLeft.get(i).x = screenW * fu * Math.cos(bet) * xyTemp.x                         / camera_high / Math.cos((anglePi2 - bet) * l)                         + screenW / 2;                 xylistLeft.get(i).valid = true;             }             else             {                 xylistLeft.get(i).valid = false;             }         }

        for (int i = 0; i < num; i++)         {             XYpoint xyTemp = new XYpoint();             xyTemp.x = xylistRight.get(i).x;             bet = Math.atan(xylistRight.get(i).y / camera_high);             if (camera_high < 0)             {                 bet = bet + PI;             }             if (((((anglePi2 - bet) * l) < (PI / 2)) && (((anglePi2 - bet) * l) > (0 - PI / 2)))                     || ((((anglePi2 - bet) * l) > (PI * 3 / 2)) && (((anglePi2 - bet) * l) < (PI * 5 / 2))))             {                 xylistRight.get(i).y = screenH * camW * fu                         * Math.tan(anglePi2 - bet) / camH + screenH / 2;                 xylistRight.get(i).x = screenW * fu * Math.cos(bet) * xyTemp.x                         / camera_high / Math.cos((anglePi2 - bet) * l)                         + screenW / 2;                 xylistRight.get(i).valid = true;             }             else             {                 xylistRight.get(i).valid = false;             }         }

        if (mCaliTrackShow)         {             drawarcLine(canvas, xylistLeft);             drawarcLine(canvas, xylistRight);             drawFlagLine(canvas);         }         else         {             drawFlagMiddleLine(canvas);         }

        return true;     }

}

 


最新回复(0)