如何在android中找到svg bezier路径的中心点

时间:2015-02-10 10:00:19

标签: android svg android-canvas

我已经通过svgparser将svg路径转换为bezier路径。 我有一个文本文件,其中我们有世界上所有国家的svg路径。我已经绘制了所有bezier路径,但现在我可以获得每条贝塞尔曲线的中心。

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.graphics.Region;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;


    public class RegionViewClass extends MapView implements View.OnTouchListener {
        Path mPath;
        Paint mPaint;
        Region mRegion;
        Context mContext;
        MapView mapView;
        int p,q;

这是3个国家的svg路径。我如何区分触摸事件的每一条路径。

        String d = "M670.98,313.01l4.58-2.24l2.72-9.84l-0.12-12.08l15.58-16.82v-3.99l3.21-1.25l-0.12-4.61l-3.46-6.73l1.98-3.61l4.33,3.99l5.56,0.25v2.24l-1.73,1.87l0.37,1l2.97,0.12l0.62,3.36h0.87l2.23-3.99l1.11-10.46l3.71-2.62l0.12-3.61l-1.48-2.87l-2.35-0.12l-9.2,6.08l0.58,3.91l-6.46-0.02l-2.28-2.79l-1.24,0.16l0.42,3.88l-13.97-1l-8.66-3.86l-0.46-4.75l-5.77-3.58l-0.07-7.37l-3.96-4.53l-9.1,0.87l0.99,3.96l4.46,3.61l-7.71,15.78l-5.16,0.39l-0.85,1.9l5.08,4.7l-0.25,4.75l-5.19-0.08l-0.56,2.36l4.31-0.19l0.12,1.87l-3.09,1.62l1.98,3.74l3.83,1.25l2.35-1.74l1.11-3.11l1.36-0.62l1.61,1.62l-0.49,3.99l-1.11,1.87l0.25,3.24L670.98,313.01L670.98,313.01z" +
            "M671.19,242.56l0.46,4.27l8.08,3.66l12.95,0.96l-0.49-3.13l-8.65-2.38l-7.34-4.37L671.19,242.56L671.19,242.56z\n" +
            "M695.4,248.08l1.55,2.12l5.24,0.04l-0.53-2.9L695.4,248.08L695.4,248.08z\n"+"M781.68,324.4l-2.31,8.68l-12.53,4.23l-3.75-4.4l-1.82,0.5l3.4,13.12l5.09,0.57l6.79,2.57v2.57l3.11-0.57l4.53-6.27v-5.13l2.55-5.13l2.83,0.57l-3.4-7.13l-0.52-4.59L781.68,324.4L781.68,324.4z\n"+
            "M473.88,227.49l-4.08-1.37l-16.98,3.19l-3.7,2.81l2.26,11.67l-6.75,0.27l-4.06,6.53l-9.67,2.32l0.03,4.75l31.85,24.35l5.43,0.46l18.11-14.15l-1.81-2.28l-3.4-0.46l-2.04-3.42v-14.15l-1.36-1.37l0.23-3.65l-3.62-3.65l-0.45-3.88l1.58-1.14l-0.68-4.11L473.88,227.49L473.88,227.49z\n";
    ;

        public RegionViewClass(Context context) {
            super(context);
            this.mContext=context;
            mPath = new Path();
            mRegion=new Region();
            mPath= SVGParser.parsePath(d);
            setFocusable(true);
            setFocusableInTouchMode(true);
            this.setOnTouchListener(this);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(Color.BLUE);
            mPaint.setStrokeWidth(20);
            RectF rectF = new RectF();
            mPath.computeBounds(rectF, true);
            mRegion.setPath(mPath, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
        }
        @Override
        protected void onDraw(Canvas canvas) {

            //canvas.drawPath(mPath, mPaint);

        }


        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Point point = new Point();
            point.x=event.getX();
            point.y = event.getY();
            invalidate();

            if(mRegion.contains((int) point.x,(int) point.y)==true)
                Toast.makeText(mContext, "inside", Toast.LENGTH_LONG).show();

            Path selectedPath=  mRegion.getBoundaryPath();
            if (mPath==selectedPath){
                Toast.makeText(mContext, "india", Toast.LENGTH_SHORT).show();
                Log.e("", "" + selectedPath);

            }

            else
                Toast.makeText(mContext, "outside", Toast.LENGTH_LONG).show();

            return true;

        }

       /* private boolean contains(int i, int j) {
        }*/

        class Point {
            float x, y;

            @Override
            public String toString() {

                return x + ", " + y;
            }
        }


    }

2 个答案:

答案 0 :(得分:0)

如果要测试用户点击路径中的哪个子路径。您需要将它们分成单独的路径定义。然后分别对它们中的每一个运行Region.contains()测试。

答案 1 :(得分:0)

您给定的路径没有贝塞尔曲线。并且不应该因为县不倾向于彼此定义弯曲的边界(除了一些例子,我们使用经度,如美国加拿大边界有曲线,因为地球是弯曲的。)

但是,如果你想要的话。计算贝塞尔曲线中心点的公式为:

t = 0.5;
x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x;
y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y;

这回答了你的第一个问题。对于正确问题的答案,你怎么知道哪个触摸是哪一个路径是更难的一个,并且假设你实际上有一个多边形,正确的答案是在多边形算法中实现一个路径。

但是,你真正想要的是有效的东西。我可以推荐一个手柄。只需在每个区域形状的形状中心绘制一些东西。然后,当人触摸屏幕时,找到距离该点最近的点。大多数国家都是模糊的圆形或通常没有奇怪的弯曲,所以只需找到边界区域然后距离中心点。

划分每个国家/地区的路径。获得该县的边界框。检查触摸是否在任何边界框内。如果是,请将触摸的接近程度与触摸框被该触摸击中的所有国家/地区的中心区域进行比较。