We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpOpenGL and 3D Libraries › A decent replacement for line() in 3D
Pages: 1 2 
A decent replacement for line() in 3D (Read 4431 times)
A decent replacement for line() in 3D
Jan 2nd, 2010, 10:56am
 
I am writing a piece of code that takes an array of beziers and draws them in 3D space. I am using Peasy cam so I can view and fly around the beziers using the mouse.

I am animating the beziers by using bezierPoint() to split up the beziers in to lines then in to another array and then using line() to draw that.

It works great but looks awful on tight sections where the lines don't match up.

I can't find any code or libraries that will draw me a decent line - can any one help?

I have tried writing a lineBox() function that draws a box along a vector and this works well - but it still looks pretty rubbish and slows the whole thing down.


James
Re: A decent replacement for line() in 3D
Reply #1 - Jan 2nd, 2010, 10:10pm
 
So is your issue with line quality... meaning the antialias or smoothness?

If so, you can add this before drawing the lines.
Code:

smooth();


If your using OpenGL there are several things you could do...
such as..
Code:

hint(DISABLE_OPENGL_2X_SMOOTH);
hint(ENABLE_OPENGL_4X_SMOOTH);
gl.glHint (gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST);
gl.glEnable (gl.GL_LINE_SMOOTH);


If you're talking about actually drawing a line...
In pure OpenGL it would look something like this.
Code:

gl.glLineWidth(3);  
gl.glColor4f(.78, .78, .78, .3);
gl.glBegin(gl.GL_LINES);
gl.glVertex3f(x1,y1,z1);
gl.glVertex3f(x2,y2,z2);
gl.glEnd();
Re: A decent replacement for line() in 3D
Reply #2 - Jan 3rd, 2010, 3:28am
 

Hello,

I can't help you with that...

It's just that I'am highly interested in your boxLine-function.

I would be very greatful if you could post that.

In fact I had similar problems when writing code for a 3D-printer because the lines were to thin for the printer. My own box-functions had problems when I rotated it, because the order of the shapes was distorted.

What is needed is a real 3D-Line (thin cylinder) which is not hollow.

Thanks!

Chris

Re: A decent replacement for line() in 3D
Reply #3 - Jan 3rd, 2010, 7:50am
 
You can set the thickness of a line using strokeWeight():
Code:

smooth();
strokeWeight(1);   // Default
line(20, 20, 80, 20);
strokeWeight(4);   // Thicker
line(20, 40, 80, 40);
strokeWeight(10);  // Beastly
line(20, 70, 80, 70);

http://processing.org/reference/strokeWeight_.html
Re: A decent replacement for line() in 3D
Reply #4 - Jan 5th, 2010, 2:16pm
 
Chrisir wrote on Jan 3rd, 2010, 3:28am:
Hello,

I can't help you with that...

It's just that I'am highly interested in your boxLine-function.

I would be very greatful if you could post that.



Not sure if this is what you are expecting Smiley

You may need to add some math to orientate the box to the camera - the Z axis is what you want to change for this.

Quote:
void drawLine(float x1, float y1, float z1, float x2, float y2, float z2, float weight, color strokeColour)
{
  PVector p1 = new PVector(x1, y1, z1);
  PVector p2 = new PVector(x2, y2, z2);
  PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
  float rho = sqrt(pow(v1.x,2)+pow(v1.y,2)+pow(v1.z,2));
  float phi = acos(v1.z/rho);
  float the = atan2(v1.y,v1.x);
  v1.mult(0.5);
  
  pushMatrix();
  translate(x1,y1,z1);
  translate(v1.x, v1.y, v1.z);
  rotateZ(the);
  rotateY(phi);
  noStroke();
  fill(strokeColour);
  box(weight,weight,p1.dist(p2)*1.2);
  popMatrix();
}



James
Re: A decent replacement for line() in 3D
Reply #5 - Jan 5th, 2010, 2:23pm
 
My issue is the way the bezier is drawn. It splits the curve up in to short straight lines. When a tight curve gets drawn on the display you end up seeing all the short lines and the gaps between them - with a kind of spikey effect.

Annoyingly I cannot post the image here until I post a few more messages Sad

James
Re: A decent replacement for line() in 3D
Reply #6 - Jan 5th, 2010, 2:24pm
 
I'll post the image...
Re: A decent replacement for line() in 3D
Reply #7 - Jan 5th, 2010, 2:24pm
 
http://www.mintylamb.co.uk/temp/bezierIssue.png
Re: A decent replacement for line() in 3D
Reply #8 - Jan 5th, 2010, 4:26pm
 
The problem is you are "converting" curves into line segments, and drawing line segments instead of curves.

In what way are you "animating" the line segments? Why not animate the curves instead?

-spxl
Re: A decent replacement for line() in 3D
Reply #9 - Jan 6th, 2010, 3:49am
 
@James Carruthers:


Thank you for posting the code!!!

Can't you work with a chain of small spheres?

Greetings,
Chris

Re: A decent replacement for line() in 3D
Reply #10 - Jan 6th, 2010, 1:53pm
 
Hi Subpixel,

Converting them in to lines is exactly what the Bezier function does internally.

I shall explore the curve function - but I guessed (perhaps wrongly) that it drew in the same way.


James
Re: A decent replacement for line() in 3D
Reply #11 - Jan 6th, 2010, 1:59pm
 
Nope - does the same thing Smiley

I need something that draws a tube from a set of 3D coordinates.


James
Re: A decent replacement for line() in 3D
Reply #12 - Jan 7th, 2010, 5:51am
 
Hello James,

first, thanks again for the great LineDraw you posted.
It looks awesome.

Second:
To your problem.
I figure your problem is that you have two small lines with a gap that looks bad.
My suggestions:
Take the 2 line-coordinates xyz from the previous loop and connect them with the 2 line-coordinates xyz from the current loop.
So you get a 3D-rectangle derived from both lines's coordinates.

That should close the gap.

at the end of each loop you need to have something like
oldFrom_X = lineFrom_X
oldFrom_Y = lineFrom_Y
oldFrom_Z = lineFrom_Z

oldTo_X = lineTo_X
oldTo_Y = lineTo_Y
oldTo_Z = lineTo_Z

the 3D rectangle is then based on 4 points:
oldFrom_X
oldFrom_Y
oldFrom_Z

oldTo_X
oldTo_Y
oldTo_Z

lineFrom_X
lineFrom_Y
lineFrom_Z

lineTo_X
lineTo_Y
lineTo_Z

In the first loop just set the old-values to the current (***only the first time - set a Flag to avoid this in later loops).

I can post some code if you like.

Greetings, Chris

 
Re: A decent replacement for line() in 3D
Reply #13 - Jan 7th, 2010, 7:49am
 
Take a look at this 3d shape library.  I think it has tubes.
http://www.lagers.org.uk/s3d4p/index.html
Re: A decent replacement for line() in 3D
Reply #14 - Jan 7th, 2010, 1:01pm
 
Thanks Chris.

In fact your suggestion was amazingly simple to utilize - I am kicking myself why I didn't think of it before.

This:
Code:

line(ps[i].x, ps[i].y, ps[i].z, ps[i+1].x, ps[i+1].y, ps[i+1].z);


changes to this:
Code:

line(ps[i].x, ps[i].y, ps[i].z, ps[i+2].x, ps[i+2].y, ps[i+2].z);


ps is an array of xyz points that make up the bezier

This improves it by a long way - you only get artifacts from very very acute angles of view. Still annoying but... better!

James
Pages: 1 2