2

enter image description here

hi all, I have this image and I wanna to draw line "the path" between the two point.

what i'm tried:

is draw the path , using main point which is save in database. "x,y for the point" and draw line between multi-points until arrive the end point. like in image number 2 enter image description here

what i'm thinking about is if I divide the image to square grid for example 15*15 ,and give each square x,y,tag where tag can be 0,1 which mean wall or any thing 0 can't walk throw it 1 u can. and create the bath dynamically.

that are all the idea that i have for now :) if there is anyother way i don't know it. plz help me :)

Update :

-The user can zoom in/out. -what i'm trying to do is something like this

4

7 回答 7

3

您可以直接修改位图,也可以在位图SurfaceView上放置一个并在SurfaceView. 在这种情况下,您所要做的就是onDrawSurfaceView.

我在我的Turtle Draw应用程序中画了很多线......这是我扩展的方式SurfaceView

public class DrawView extends SurfaceView {

    Paint paint = new Paint();

    List < float[] > lines = new ArrayList < float[] > ();
    List < Integer > colors = new ArrayList < Integer > ();
    int curColor = Color.WHITE;
    int bgColor = Color.BLACK;

    Bitmap mBitmap;

    ImageView turtle;

    float curX, curY, curTurn = 0f;

    Matrix transform = new Matrix();

    public DrawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBitmap = getBitmapFromDrawable(context);
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(DpiUtils.getPxFromDpi(getContext(), 2));
        setScrollContainer(true);
        // clear();
    }

    public DrawView(Context context) {
        super(context);

    }

    public void addLine(float...l) {
        synchronized(lines) {
            lines.add(l);
            colors.add(curColor);
        }
    }

    public List < float[] > getLines() {
        return lines;
    }

    public List < Integer > getColors() {
        return colors;
    }

    @Override
    public void onDraw(final Canvas canvas) {

        synchronized(lines) {
            super.onDraw(canvas);
            int i = 0;
            for (float[] l: lines) {
                paint.setAntiAlias(true);
                paint.setColor(colors.get(i++));
                canvas.drawLines(l, paint);
                curX = l[2];
                curY = l[3];
            }

            transform.setTranslate(curX - 13, curY - 13);
            transform.preRotate(360 - curTurn, 13, 13);

            paint.setColor(Color.BLACK);
            canvas.drawBitmap(mBitmap, transform, paint);
        }
    }

    public void setTurn(float turn) {
        this.curTurn = turn;
    }

    public void clear() {
        lines.clear();
        colors.clear();
        DisplayMetrics metrics = DpiUtils.getDisplayMetrics(getContext());

        curX = metrics.widthPixels / 2f;
        curY = (metrics.heightPixels / 2f) - DpiUtils.getPxFromDpi(getContext(), 50);
        curTurn = 0;

        scrollTo(0, 0);
    }

    public static Bitmap getBitmapFromAsset(Context context, String strName) {
        AssetManager assetManager = context.getAssets();

        InputStream istr;
        Bitmap bitmap = null;
        try {
            istr = assetManager.open(strName);
            bitmap = BitmapFactory.decodeStream(istr);
        } catch (IOException e) {
            return null;
        }

        return bitmap;
    }

    public static Bitmap getBitmapFromDrawable(Context context) {
        Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.turtle_26);
        return icon;
    }

    public void setDrawColor(int color) {
        paint.setColor(color);
        curColor = color;
    }

    public int getDrawColor() {
        return curColor;
    }

    int x, y = 0;
    int scrollByX, scrollByY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int action = (event.getAction() & MotionEvent.ACTION_MASK);

        if (action == MotionEvent.ACTION_DOWN) {
            x = (int) event.getX() + scrollByX;
            y = (int) event.getY() + scrollByY;
        } else if (action == MotionEvent.ACTION_MOVE) {
            scrollByX = x - (int) event.getX();
            scrollByY = y - (int) event.getY();
            scrollTo(scrollByX, scrollByY);
        }

        return true;
    }

    @Override
    public void scrollTo(int x, int y) {
        // TODO Auto-generated method stub
        super.scrollTo(x, y);
        scrollByX = x;
        scrollByY = y;
    }

    @Override
    public void setBackgroundColor(int color) {
        // TODO Auto-generated method stub
        super.setBackgroundColor(color);
        bgColor = color;
    }

    public int getBackgroundColor() {
        return bgColor;
    }

}
于 2013-09-26T23:55:44.640 回答
2

您可以使用Dijkstra's_algorithm找到最短路径。

在此处输入图像描述

有更有效的方法可以做到这一点,比如A*算法,但我认为 Dijkstra 最容易实现。

于 2013-10-29T14:08:43.353 回答
2

您可以使用Path类。祝你好运!

于 2013-09-26T23:51:21.577 回答
2

如果我理解得很好,您的主要问题不是在图像上画线。您正在搜索 WHICH PATH 以动态方式获取给定地图。这个对吗?

好吧,如果是这种情况,您正在寻找A* 搜索算法。这是一种众所周知的寻路方法,在需要这种 AI 的游戏和其他应用程序中非常常见。

您可以开发自己的算法实现,以满足您的需求,或者您可以尝试使用来自第 3 方的 API。

这是可以从谷歌代码中使用的一个。它是简单的 java 和 apache 许可证,因此可以在您的 android 应用程序中使用。

但是等等,我也简单地看了一下 github,似乎还有很多不同的实现可供使用!

搜索网络,你还会发现很多文章、教程、论文......

祝你好运!

编辑

正如您在下面的评论中解释的那样,您的主要问题是动态处理“地图”以查找“墙壁”,以便您可以应用 A* 搜索,然后最后在所有这些之上绘制线条。

好吧,要动态处理图像,您将需要一些 3rd 方库来执行此操作,那里有很多,但可能更好的解决方案是使用OpenCV。它与 android 兼容,有很好的文档和很多关于它的文章。这是一个教程,其中包含在图像中查找“线条”的示例。这也可以应用于您的地图。可能您需要调整阈值,直到仅检测到墙壁的较粗线条。

于 2013-10-23T14:14:02.567 回答
0

尝试在您的图像中搜索白色像素(这将是您可以行走的路径)

于 2013-10-28T12:46:41.243 回答
0

我的回答假设您正在尝试计算某人从黑色圆圈到红色圆圈的最简单路径。如果您只是在实际绘制线条方面寻求帮助,请忽略此答案。我还假设您可以提前定义所有交点。如果您需要从图片中以编程方式派生它们,您可能应该从一个新问题开始。

我将从您建议的 (x,y) 点开始,但不要使用标签值。然后,我会将这些点之间的连接添加为相关对象,该对象比您的标签值添加更多细节。每个点都有一组到其他相邻点的连接。在每个连接上,我都会在计算中使用一堆属性,例如距离、障碍物和任何其他增强功能,例如特权。距离很容易(提示:使用勾股定理)。障碍可能包括门、台阶、电梯等。特权可能包括限制进入的区域(靠近图表顶部的对角走廊看起来受到限制)。

看起来在黑色的起点你可以向东或向西。那将是两条不同的道路。向东的第一个点将提供四种选择:通过向北的门、向南的门、继续向东或向西返回。西选项将返回到路径可以被忽略为循环的原始点。向南的选项只会返回到可以忽略为循环的这一点。向北的选择很有趣,因为它应该继续穿过对角线走廊并最终提供通往目的地的路径,尽管显然不是最佳路径。向东的选项将继续并最终返回几个选项。当一条路径到达目的地时,它会根据经过的连接(距离、

实现这一点将涉及引入一个路径,该路径包括经过的点列表以及沿这些点的每个连接的累积难度。从原点开始,我会尝试编写一些向各个方向扩展一步的东西,而不是尝试完全遍历每条路径。增加每一步的累积难度。如果该点是目的地,那么您就有了一条成功的路径(尽管它可能不是最有效的路径)。如果该点已经在路径中,则它是一个循环,因此停止遍历该路径。如果路径的累积难度大于已经找到的另一条路径,则停止遍历该路径。

于 2013-10-28T16:09:36.243 回答
0

我认为如果不使用 OpenGL(并让它完成将线条的 X/Y 位置转换为屏幕上的实际 X/Y 位置的工作),这是不可能的。

在 OpenGL 中,您将在 2D 平面中渲染平面图图像。您需要预先计算要在其之间绘制线条的每个交点的世界空间位置 (x,y,z),并创建一个集合,其中每个位置都有一个可以连接到的其他位置的数组。然后,您需要执行(递归)逻辑来确定起点和终点之间的点,并在每个点之间绘制 2D 线。

所以,这是很有可能的,但是平移和缩放的需要几乎不需要相机,这就是 OpenGL 的用武之地。

平移和缩放将通过四处移动相机来处理,同时将其保持在预定义的范围内,以便(基于选择的 FOV)它不会显示(太多)超出图像边缘。

于 2013-10-28T23:06:06.273 回答