Canvas.drawLines 显示不相交的线段

发布于 2024-11-10 11:23:02 字数 1881 浏览 2 评论 0原文

可能的重复:
Android 如何跟随手指绘制平滑的线条

我是 Android 和 Java 编程新手,并且一直在尝试移动应用程序开发。我最近创建了一个视图,它只是使绘制的线条与用户手指的移动保持同步。但是,我在使用 Canvas.drawLines 方法时遇到了一些问题。

我得到的不是在所有点之间获得一组连续的线,而是在段之间有中断的虚线图案:

Broken Line Segments in Canvas.DrawLines

这是一个示例数据集和简单的代码来重现该问题(点数据取自真实的手指滑动):

public class SomeView extends android.view.View 
{
    private float[] _data = { 292.36545f, 104.37576f, 285.3567f, 112.39249f, 274.34293f, 113.39456f, 254.3179f, 115.39874f, 248.3104f, 116.40082f, 228.28535f, 118.405f, 214.26784f, 119.407104f, 211.26408f, 119.407104f, 204.25533f, 120.40918f, 202.25282f, 120.40918f, 201.25157f, 121.411255f, 199.24907f, 124.41754f, 197.24657f, 125.41962f, 196.24532f, 130.43005f, 195.24406f, 139.44885f, 197.24657f, 144.45929f };
    private Paint _paint;

    public SomeView( Context c, AttributeSet attrs)
    {
        super( c, attrs );
        _paint = new Paint();
        _paint.setColor(Color.BLUE);
        _paint.setStrokeWidth(6);   
    }   

    @Override
    public void onDraw(Canvas canvas)
    {       
        canvas.drawLines( _data, _paint);
    }           
}

绘制出每个点并将其覆盖在线上之后,我意识到问题实际上是每个点都没有连接,只有每两个点连接。该方法不是将点 1 连接到点 2、点 3 等,而是将 1 连接到 2,然后将 3 连接到 4,如下所示:

在此处输入图像描述

我可以通过再次调用 drawLines 并提供偏移量来几乎获得我想要的内容,以便将其他对绘制在一起,如下所示好吧,但这对我来说似乎效率低下,而且通常很笨重,而且线条仍然不完全平滑(在拐角处稍微不稳定)。

所以,我的问题是;我做错了什么以及如何在给定一定数量的点的情况下绘制一条简单、平滑的线?哎呀,忘记了这些要点,如果有更好的方法来用一条线追踪用户的手指,我会洗耳恭听。提前致谢。

Possible Duplicate:
Android How to draw a smooth line following your finger

I'm new to Android and java programming and have been playing around a bit with mobile app development. I recently created a View which simply keeps draws lines in step with the user's finger movements. However, I've been having some trouble with the Canvas.drawLines method.

Instead of getting a continuous set of lines between all points I am getting more of a dashed pattern with breaks between segments:

Broken Line Segments in Canvas.DrawLines

Here is a sample set of data and simple code to reproduce the issue (point data was taken from a real finger swipe):

public class SomeView extends android.view.View 
{
    private float[] _data = { 292.36545f, 104.37576f, 285.3567f, 112.39249f, 274.34293f, 113.39456f, 254.3179f, 115.39874f, 248.3104f, 116.40082f, 228.28535f, 118.405f, 214.26784f, 119.407104f, 211.26408f, 119.407104f, 204.25533f, 120.40918f, 202.25282f, 120.40918f, 201.25157f, 121.411255f, 199.24907f, 124.41754f, 197.24657f, 125.41962f, 196.24532f, 130.43005f, 195.24406f, 139.44885f, 197.24657f, 144.45929f };
    private Paint _paint;

    public SomeView( Context c, AttributeSet attrs)
    {
        super( c, attrs );
        _paint = new Paint();
        _paint.setColor(Color.BLUE);
        _paint.setStrokeWidth(6);   
    }   

    @Override
    public void onDraw(Canvas canvas)
    {       
        canvas.drawLines( _data, _paint);
    }           
}

After plotting out each point and overlaying it atop the line I realized that the problem is actually that each point is not being connected, only every two points. Instead of connecting point 1 to point 2 to point 3 and so on, the method is connecting 1 to 2 and then 3 to 4 as shown below:

enter image description here

I can almost get what I want by drawing calling drawLines again and providing an offset this time so that the other pairs are drawn together as well, but this seems inefficient and generally clunky to me, and the line still isn't completely smooth (gets slightly choppy on corners).

So, my question is; what am I doing wrong and how can I draw a simple, smooth line given some number of points? Heck, forget the points, if there is a better way to trace the user's finger with a line I am all ears. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久伴你 2024-11-17 11:23:02

您得到的正是 drawLines 文档中指定的内容。

做你想做的事情的一种方法是构造一个 Path从该数据中,并使用drawPath而不是drawLines。类似于:

Path _path = new Path();
_path.moveTo(_data[0], _data[1]);
for (int i=2; i<_data.length; i+=2) {
  _path.lineTo(_data[i], _data[i+1]);
}

然后用以下方式绘制它:

_canvas.drawPath(_path, _paint)

来自 Path 文档:

Path 类封装了由直线段、二次曲线和三次曲线组成的复合(多轮廓)几何路径。它可以使用 canvas.drawPath(path,paint) 进行绘制,可以是填充的,也可以是描边的(基于paint的样式

所以你可能需要改变你的绘画风格以获得正确的效果。

What you get is exactly what is specified in the drawLines documentation.

One way of doing what you want would be to construct a Path from that data, and use drawPath rather than drawLines. Something like:

Path _path = new Path();
_path.moveTo(_data[0], _data[1]);
for (int i=2; i<_data.length; i+=2) {
  _path.lineTo(_data[i], _data[i+1]);
}

Then draw it with:

_canvas.drawPath(_path, _paint)

From the Path docs:

The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint's Style)

So you might have to change you're paint's style to get the right effect.

夜深人未静 2024-11-17 11:23:02

我今晚刚刚遇到这个问题。对于其他面临这个问题的人来说,问题是Android不会从点1绘制到点2,然后从点2到点3,从点3到点4等。它会绘制点1到2,然后从点3到4等等。因此,您还可以将前一点两次推入您使用的任何数据结构中(我使用的是 Vector)。所以:

private Vector<Float> mPoints = new Vector<Float>();
private float mLastX = Float.NaN;
private float mLastY = Float.NaN;

public void addPoint(float x, float y) {
    if (mLastX == Float.NaN || mLastY == Float.NaN) {
        mLastX = x;
        mLastY = y;
    } else {
        mPoints.add(mLastX);
        mPoints.add(mLastY);
        mPoints.add(x);
        mPoints.add(y);

        mLastX = x;
        mLastY = y;
    }
}

然后确保将 mPoints 转换为 float[] 并将其传递给canvas.drawLines()。

I just ran into this issue tonight. For anyone else facing this, the problem is that Android doesn't draw from point 1 to point 2, then point 2 to point 3, point 3 to point 4, etc. It will draw point 1 to 2, then point 3 to 4, etc. So you can also push the previous point twice into whatever data structure you use (I used Vector). So:

private Vector<Float> mPoints = new Vector<Float>();
private float mLastX = Float.NaN;
private float mLastY = Float.NaN;

public void addPoint(float x, float y) {
    if (mLastX == Float.NaN || mLastY == Float.NaN) {
        mLastX = x;
        mLastY = y;
    } else {
        mPoints.add(mLastX);
        mPoints.add(mLastY);
        mPoints.add(x);
        mPoints.add(y);

        mLastX = x;
        mLastY = y;
    }
}

Then just make sure to convert your mPoints to a float[] and pass that to canvas.drawLines().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文