views:

232

answers:

4

I want to draw a line with thickness in j2me. This can easily be achieved in desktop java by setting Pen width as thickness value. However in j2me, Pen class does not support width. My idea is to generate a polygon from the line I have, that resembles the line with thickness i want to draw. In picture, on the left is what I have, a line with points. On the right is what I want, a polygon that when filled, a line with thickness. Could anyone know how to generate a polygon from line?

alt text

A: 

This will draw a line:

Graphics g = this.CreateGraphics();
Pen pen = new Pen(Color.Black, 2); //black Width 2
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
g.DrawLine(pen, point1, point2); //point1 and point2 are instances of Point class

So i guess if you have an array of points you could do something like

for(int i=0;i<myPoints.Length-1;i++)
g.DrawLine(pen,myPoints[i],myPoints[i+1]); 

question is not very clear... hope this helps

m0s
This perfectly draw the intended result in C#, I knew. I would like to do the same thing in j2me which does not support Pen width. So I'm trying to create a polygon out of a line to draw a line with thickness.
VOX
@mOs: I think this will help but it will draw line only above/ below the original line. I guess VOX need the thick line equally on both the sides of the original route. So I guess if he want a line of thickness 10, he want thickness of 5 above original line and thickness of 5 below original line.
Ram
Yes @Ram, it is as you said and as @m0s' code. But in j2me Pen doesn't support second width argument making me unable to use @m0s' code.
VOX
@VOX now I see your problem... unfortunately I have no idea about j2me programming... however, here is a suggestion... I am sure you can draw triangles in j2me... So, index the points in zigzag manner, then go over them in a loop and draw triangles for each next 3 points, performance might be horrible but it will do the trick.
m0s
Thanks for the trick m0s, however, those little things that run j2me have horrible performance. With your trick, I could probably have to wait a long time to finish rendering. I'm drawing a map. Even if I found a way to generate polygons, I'll have to pre-generate them on desktop. So, any ideas?
VOX
A: 

I guess I'll draw parallel lines beside the line and connect them as a polygon. Than fill. To draw a parallel line, http://stackoverflow.com/questions/2825412/draw-a-parallel-line.

VOX
It seems to me that if you essentially turn each segment of the line into a rectangle of the same length, and whatever thickness/width you're aiming for, that you will have ugly corners.
Dan
Exactly, I'm now having ugly corners. Any pointer to round those corners?
VOX
A: 

Unfortunately, the general algorithm for this is pretty complicated, and if you're drawing a map, you probably need the general algorithm... The TinyLine library looks promising, if you can spend the money, see, for example:

http://www.tinyline.com/2d/download/guide/gstate.html#joinStyle

Chances are, this will help you with other things you'll want to do in drawing your map, too.

I haven't used the library (or done any J2ME programming, frankly), but if it does what it claims, it seems likely to be worth the money.

Steven Ourada
TinyLine is too expensive to effort at the moment and it costs a lot of time to draw a map with that. My idea is to preprocess these lines into polygons and save them. Then the running j2me app just need to read those saved polygons without any processing and draw directly on screen.
VOX
+3  A: 

Ah, if you're preprocessing, that should make your life easier. Here's a little code I whipped up using Graphics2D (using J2SE). I don't like that the output includes extra interior segments, but when it's filled, it looks pretty good.

import java.awt.BasicStroke;
import java.awt.Shape;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;

public class StrokePath
{
    public static void main(String[] args)
    {
        // set line width to 6, use bevel for line joins
        BasicStroke bs = new BasicStroke(6.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL);

        // create a path for the input
        Path2D p = new Path2D.Float();
        p.moveTo(50.0, 50.0);
        p.lineTo(65.0, 100.0);
        p.lineTo(70.0, 60.0);
        p.lineTo(120.0, 65.0);
        p.lineTo(40.0, 200.0);

        // create outline of wide lines by stroking the path with the stroke
        Shape s = bs.createStrokedShape(p);
        // output each of the segments of the stroked path for the output polygon
        PathIterator pi = s.getPathIterator(null);
        while (!pi.isDone())
        {
            pi.next();
            double[] coords = new double[6];
            int type = pi.currentSegment(coords);
            switch (type)
            {
            case PathIterator.SEG_LINETO:
                System.out.println(String.format("SEG_LINETO %f,%f", coords[0], coords[1]));
                break;
            case PathIterator.SEG_CLOSE:
                System.out.println("SEG_CLOSE");
                break;
            case PathIterator.SEG_MOVETO:
                System.out.println(String.format("SEG_MOVETO %f,%f", coords[0], coords[1]));
                break;
            default:
                System.out.println("*** More complicated than LINETO... Maybe should use FlatteningPathIterator? ***");
                break;
            }
        }
    }
}

Here are my results after rendering these coordinates:

Unfilled Filled

Steven Ourada
This is great. You knew exactly what I wanted. thanks ;)
VOX
Glad we got it!
Steven Ourada