shariq

05-05-2015, 12:21 AM

Hi,

I need a plane at an altitude say h from earth's surface. I am going to use this to clip a sphere. In normal cartesian coordination system, I am able to visualize it. But when it comes to a globe, I have few doubts:

1.) The units that i follow is in meters, so I draw a plane that is at a height of (earth's radius + h) meters from earth's core(0,0,0). Is this correct? or some conversion is required.

2.) I fail to understand whether the axes of globe(x,y,z) are fixed or not, i mean if they are fixed then let say z axis is normal at longitude 0 degrees, then if I am standing at lat lon (32.5, 75.2) then how can the equation of the plane tangent to the surface at this location be z=radius of earth at (32.5, 75.2). It should be in terms of x,y,z and not z alone. isn't it?

To my help my api provides the conversion from latlon to cartesian coords(Vec4) as required by openGL.

Vec4 centerPoint = this.computePointFromPosition(dc,

this.location.getLatitude(), this.location.getLongitude(), altitudes[0], terrainConformant[0]);

I create a plane at this location:

DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] {centerPoint.getX(), centerPoint.getY(), centerPoint.getZ(), centerPoint.getW()}); //Some thing wrong with this Please check if this equation is correct

eqn1.flip();

gl.glClipPlane(GL.GL_CLIP_PLANE0, eqn1);

gl.glEnable(GL.GL_CLIP_PLANE0);

Here is the code, please check the equation of plane and let me know if some modification is required:

@Override

public void drawSphere(DrawContext dc)

{

double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());

boolean[] terrainConformant = this.isTerrainConforming();

int subdivisions = this.getSubdivisions();

if (this.isEnableLevelOfDetail())

{

DetailLevel level = this.computeDetailLevel(dc);

Object o = level.getValue(SUBDIVISIONS);

if (o != null && o instanceof Integer)

subdivisions = (Integer) o;

}

Vec4 centerPoint = this.computePointFromPosition(dc,

this.location.getLatitude(), this.location.getLongitude(), altitudes[0], terrainConformant[0]);

Matrix modelview = dc.getView().getModelviewMatrix();

modelview = modelview.multiply(Matrix.fromTranslation(centerPo int));

modelview = modelview.multiply(Matrix.fromScale(this.getRadius ()));

double[] matrixArray = new double[16];

modelview.toArray(matrixArray, 0, false);

this.setExpiryTime(-1L); // Sphere geometry never expires.

GL gl = dc.getGL(); // GL initialization checks for GL2 compatibility.

gl.glPushAttrib(GL.GL_POLYGON_BIT | GL.GL_TRANSFORM_BIT);

try

{

gl.glEnable(GL.GL_CULL_FACE);

gl.glFrontFace(GL.GL_CCW);

// Were applying a scale transform on the modelview matrix, so the normal vectors must be re-normalized

// before lighting is computed. In this case we're scaling by a constant factor, so GL_RESCALE_NORMAL

// is sufficient and potentially less expensive than GL_NORMALIZE (or computing unique normal vectors

// for each value of radius). GL_RESCALE_NORMAL was introduced in OpenGL version 1.2.

gl.glEnable(GL.GL_RESCALE_NORMAL);

gl.glMatrixMode(GL.GL_MODELVIEW);

//clipping

//double eRad = canvas.getModel().getGlobe().getRadiusAt(location) ;//added this to clipping height to come to earth's surface from core, please check this

DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] {centerPoint.getX(), centerPoint.getY(), centerPoint.getZ(), centerPoint.getW()}); //Some thing wrong with this Please check if this equation is correct

eqn1.flip();

gl.glClipPlane(GL.GL_CLIP_PLANE0, eqn1);

gl.glEnable(GL.GL_CLIP_PLANE0);

gl.glPushMatrix();

try

{

gl.glLoadMatrixd(matrixArray, 0);

this.drawUnitSphere(dc, subdivisions);

}

finally

{

gl.glPopMatrix();

}

}

finally

{

gl.glPopAttrib();

}

}

@Override

public void drawUnitSphere(DrawContext dc, int subdivisions)

{

Object cacheKey = new Geometry.CacheKey(this.getClass(), "Sphere", subdivisions);

Geometry geom = (Geometry) this.getGeometryCache().getObject(cacheKey);

if (geom == null || this.isExpired(dc, geom))

{

if (geom == null)

geom = new Geometry();

this.makeSphere(1.0, subdivisions, geom);

this.updateExpiryCriteria(dc, geom);

this.getGeometryCache().add(cacheKey, geom);

}

this.getRenderer().drawGeometry(dc, geom);

}

@Override

public void makeSphere(double radius, int subdivisions, Geometry dest)

{

GeometryBuilder gb = this.getGeometryBuilder();

gb.setOrientation(GeometryBuilder.OUTSIDE);

GeometryBuilder.IndexedTriangleArray ita = gb.tessellateSphere((float) radius, subdivisions);

float[] normalArray = new float[3 * ita.getVertexCount()];

gb.makeIndexedTriangleArrayNormals(ita, normalArray);

dest.setElementData(GL.GL_TRIANGLES, ita.getIndexCount(), ita.getIndices());

dest.setVertexData(ita.getVertexCount(), ita.getVertices());

dest.setNormalData(ita.getVertexCount(), normalArray);

}

I need a plane at an altitude say h from earth's surface. I am going to use this to clip a sphere. In normal cartesian coordination system, I am able to visualize it. But when it comes to a globe, I have few doubts:

1.) The units that i follow is in meters, so I draw a plane that is at a height of (earth's radius + h) meters from earth's core(0,0,0). Is this correct? or some conversion is required.

2.) I fail to understand whether the axes of globe(x,y,z) are fixed or not, i mean if they are fixed then let say z axis is normal at longitude 0 degrees, then if I am standing at lat lon (32.5, 75.2) then how can the equation of the plane tangent to the surface at this location be z=radius of earth at (32.5, 75.2). It should be in terms of x,y,z and not z alone. isn't it?

To my help my api provides the conversion from latlon to cartesian coords(Vec4) as required by openGL.

Vec4 centerPoint = this.computePointFromPosition(dc,

this.location.getLatitude(), this.location.getLongitude(), altitudes[0], terrainConformant[0]);

I create a plane at this location:

DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] {centerPoint.getX(), centerPoint.getY(), centerPoint.getZ(), centerPoint.getW()}); //Some thing wrong with this Please check if this equation is correct

eqn1.flip();

gl.glClipPlane(GL.GL_CLIP_PLANE0, eqn1);

gl.glEnable(GL.GL_CLIP_PLANE0);

Here is the code, please check the equation of plane and let me know if some modification is required:

@Override

public void drawSphere(DrawContext dc)

{

double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());

boolean[] terrainConformant = this.isTerrainConforming();

int subdivisions = this.getSubdivisions();

if (this.isEnableLevelOfDetail())

{

DetailLevel level = this.computeDetailLevel(dc);

Object o = level.getValue(SUBDIVISIONS);

if (o != null && o instanceof Integer)

subdivisions = (Integer) o;

}

Vec4 centerPoint = this.computePointFromPosition(dc,

this.location.getLatitude(), this.location.getLongitude(), altitudes[0], terrainConformant[0]);

Matrix modelview = dc.getView().getModelviewMatrix();

modelview = modelview.multiply(Matrix.fromTranslation(centerPo int));

modelview = modelview.multiply(Matrix.fromScale(this.getRadius ()));

double[] matrixArray = new double[16];

modelview.toArray(matrixArray, 0, false);

this.setExpiryTime(-1L); // Sphere geometry never expires.

GL gl = dc.getGL(); // GL initialization checks for GL2 compatibility.

gl.glPushAttrib(GL.GL_POLYGON_BIT | GL.GL_TRANSFORM_BIT);

try

{

gl.glEnable(GL.GL_CULL_FACE);

gl.glFrontFace(GL.GL_CCW);

// Were applying a scale transform on the modelview matrix, so the normal vectors must be re-normalized

// before lighting is computed. In this case we're scaling by a constant factor, so GL_RESCALE_NORMAL

// is sufficient and potentially less expensive than GL_NORMALIZE (or computing unique normal vectors

// for each value of radius). GL_RESCALE_NORMAL was introduced in OpenGL version 1.2.

gl.glEnable(GL.GL_RESCALE_NORMAL);

gl.glMatrixMode(GL.GL_MODELVIEW);

//clipping

//double eRad = canvas.getModel().getGlobe().getRadiusAt(location) ;//added this to clipping height to come to earth's surface from core, please check this

DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] {centerPoint.getX(), centerPoint.getY(), centerPoint.getZ(), centerPoint.getW()}); //Some thing wrong with this Please check if this equation is correct

eqn1.flip();

gl.glClipPlane(GL.GL_CLIP_PLANE0, eqn1);

gl.glEnable(GL.GL_CLIP_PLANE0);

gl.glPushMatrix();

try

{

gl.glLoadMatrixd(matrixArray, 0);

this.drawUnitSphere(dc, subdivisions);

}

finally

{

gl.glPopMatrix();

}

}

finally

{

gl.glPopAttrib();

}

}

@Override

public void drawUnitSphere(DrawContext dc, int subdivisions)

{

Object cacheKey = new Geometry.CacheKey(this.getClass(), "Sphere", subdivisions);

Geometry geom = (Geometry) this.getGeometryCache().getObject(cacheKey);

if (geom == null || this.isExpired(dc, geom))

{

if (geom == null)

geom = new Geometry();

this.makeSphere(1.0, subdivisions, geom);

this.updateExpiryCriteria(dc, geom);

this.getGeometryCache().add(cacheKey, geom);

}

this.getRenderer().drawGeometry(dc, geom);

}

@Override

public void makeSphere(double radius, int subdivisions, Geometry dest)

{

GeometryBuilder gb = this.getGeometryBuilder();

gb.setOrientation(GeometryBuilder.OUTSIDE);

GeometryBuilder.IndexedTriangleArray ita = gb.tessellateSphere((float) radius, subdivisions);

float[] normalArray = new float[3 * ita.getVertexCount()];

gb.makeIndexedTriangleArrayNormals(ita, normalArray);

dest.setElementData(GL.GL_TRIANGLES, ita.getIndexCount(), ita.getIndices());

dest.setVertexData(ita.getVertexCount(), ita.getVertices());

dest.setNormalData(ita.getVertexCount(), normalArray);

}