源代码
import android.graphics.Color;
import android.opengl.GLES20;
import java.util.Stack;
import org.rajawali3d.math.vector.Vector3.Axis;
import org.rajawali3d.Object3D;
import org.rajawali3d.math.vector.Vector3;
public class MyLine3D extends Object3D {
protected Stack<Vector3> mPoints;
protected float mLineThickness;
protected int[] mColors;
private Axis mUpAxis;
public MyLine3D() {
}
public MyLine3D(Stack<Vector3> points, float thickness, int color) {
this(points, thickness, null);
setColor(color);
}
public MyLine3D(Stack<Vector3> points, float thickness, int[] colors) {
this(points, thickness, colors, true);
}
public MyLine3D(Stack<Vector3> points, float thickness, int[] colors, boolean createVBOs) {
super();
mPoints = points;
mLineThickness = thickness;
mColors = colors;
if (colors != null && colors.length != points.size())
throw new RuntimeException("The number of line points and colors is not the same.");
mUpAxis = Axis.Z;
init(createVBOs);
}
public void setColor(int color) {
mColor[RED] = Color.red(color) / 255.f;
mColor[GREEN] = Color.green(color) / 255.f;
mColor[BLUE] = Color.blue(color) / 255.f;
mColor[ALPHA] = Color.alpha(color) / 255.f;
mOverrideMaterialColor = true;
}
public Vector3 getPoint(int point) {
return mPoints.get(point);
}
public Vector3 normalize(Vector3 v3) {
double length = Math.sqrt(v3.x * v3.x + v3.y * v3.y + v3.z * v3.z);
if (length != 0) {
return new Vector3(v3.x / length, v3.y / length, v3.z / length);
}
throw new IllegalArgumentException("Cannot normalize a zero vector.");
}
protected void init(boolean createVBOs) {
setDoubleSided(true);
setDrawingMode(GLES20.GL_TRIANGLES);
int numPoints = mPoints.size();
int numVertices = numPoints * 2;
float[] normals = new float[numVertices * 3];
float[] vertices = new float[numVertices * 3];
int[] indices = new int[(numPoints - 1) * 6];
float[] colors = new float[numVertices * 4];
for (int index = 0; index < numPoints -1; index++) {
Vector3 p1 = mPoints.get(index);
Vector3 p2 = mPoints.get(index + 1);
if(Math.abs(p2.x - p1.x) <= 0.0001){
double newP2X = p1.x / Math.abs(p1.x) * (Math.abs(p1.x) + 0.001);
p2.x = newP2X;
}
if(Math.abs(p2.y - p1.y) <= 0.0001){
double newP2Y = p1.y / Math.abs(p1.y) * (Math.abs(p1.y) + 0.001);
p2.y = newP2Y;
}
mPoints.set(index + 1, p2);
Vector3 dir = normalize(p2.clone().subtract(p1));
Vector3 normal = new Vector3(-dir.y, dir.x, 0);
normal.multiply(mLineThickness / 2);
Vector3 left1 = p1.clone().add(normal);
Vector3 right1 = p1.clone().subtract(normal);
int verticeIndex = index * 6;
vertices[verticeIndex] = (float) left1.x;
vertices[verticeIndex + 1] = (float) left1.y;
vertices[verticeIndex + 2] = (float) left1.z;
vertices[verticeIndex + 3] = (float) right1.x;
vertices[verticeIndex + 4] = (float) right1.y;
vertices[verticeIndex + 5] = (float) right1.z;
if(index == numPoints - 2){
Vector3 left2 = p2.clone().add(normal);
Vector3 right2 = p2.clone().subtract(normal);
vertices[verticeIndex + 6] = (float) left2.x;
vertices[verticeIndex + 7] = (float) left2.y;
vertices[verticeIndex + 8] = (float) left2.z;
vertices[verticeIndex + 9] = (float) right2.x;
vertices[verticeIndex + 10] = (float) right2.y;
vertices[verticeIndex + 11] = (float) right2.z;
}
}
for(int index = 0; index < numVertices; index++){
int normalIndex = index * 3;
normals[normalIndex] = mUpAxis == Axis.X ? 1 : 0;
normals[normalIndex + 1] = mUpAxis == Axis.Y ? 1 : 0;
normals[normalIndex + 2] = mUpAxis == Axis.Z ? 1 : 0;
}
for(int index = 1; index < numPoints; index ++){
int indiceIndex = (index - 1) * 6;
indices[indiceIndex] = index * 2;
indices[indiceIndex + 1] = index * 2 - 2;
indices[indiceIndex + 2] = index * 2 + 1;
indices[indiceIndex + 3] = index * 2 + 1;
indices[indiceIndex + 4] = index * 2 - 2;
indices[indiceIndex + 5] = index * 2 -1;
}
for (int index = 0; index < numVertices; index++)
{
int colorIndex = index * 4;
colors[colorIndex] = 1.0f;
colors[colorIndex + 1] = 1.0f;
colors[colorIndex + 2] = 1.0f;
colors[colorIndex + 3] = 1.0f;
}
setData(vertices, normals, null, colors, indices, createVBOs);
vertices = null;
normals = null;
colors = null;
indices = null;
}
public void preRender() {
super.preRender();
}
public void setLineThickness(final float lineThickness) {
mLineThickness = lineThickness;
}
public float getLineThickness() {
return mLineThickness;
}
}
使用
绘制圆曲线
Stack<Vector3> vector3s = new Stack<>();
double rad = 2 * Math.PI;
double part = rad / 360;
for (int index = 0; index <= 360; index++) {
double x = Math.cos(index * part) * 5;
double y = Math.sin(index * part) * 5;
vector3s.add(new Vector3(x, y, 0));
}
vector3s.add(vector3s.get(0));
Stack<Vector3> points = new Stack<>();
MyLine3D myLine3D = new MyLine3D (vector3s, 0.5, Color.RED);
Material material = new Material();
myLine3D .setMaterial(material);
scene.addChild(myLine3D );
效果图:
绘制直线:
Stack<Vector3> points = new Stack<>();
points.add(new Vector3(-11,0,0));
points.add(new Vector3(11,0,0));
MyLine3D myLine3D = new MyLine3D (points , 0.5, Color.RED);
Material material = new Material();
myLine3
D .setMaterial(material);
scene.addChild(myLine3D );
效果图: