I have a problem of finding the angle of three points with mouse pointer. The rotation doesn't following the mouse as the mouse move around the rotating object.
This is my formula :
double degree = Math.toDegrees( Math.atan2(
(now.y - point.y) - (previous.y - point.y),
(now.x - point.x) - (previous.x - point.x)));
Log.w("RESULT", "DEGREE = " + degree);
if ( degree < 0 )
degree = 360 - (-degree);
This last 2 line was added later.
This is the full code of tracking the mouse rotation.
Camera camera = Camera.getInstance();
if (event.getActionMasked() == MotionEvent.ACTION_DOWN &&
event.getPointerCount() == 1) {
previous = new Point(event.getX(), event.getY());
previous = camera.getMapPoint(previous);
}
else if (event.getActionMasked() == MotionEvent.ACTION_MOVE &&
event.getPointerCount() == 1)
{
Point now = new Point(event.getX(), event.getY());
now = camera.getMapPoint(now);
ArrayList<GameObject> list = mObject.getSubObjects();
GameObject part = list.get(0);
Point point = part.getPolygon().getCenter();
Log.w("RESULT", "Previous = " + previous.x + " " + previous.y);
Log.w("RESULT", "Next = " + now.x + " " + now.y);
Log.w("RESULT", "Center = " + point.x + " " + now.y);
double degree = Math.toDegrees( Math.atan2(
(now.y - point.y) - (previous.y - point.y),
(now.x - point.x) - (previous.x - point.x)));
Log.w("RESULT", "DEGREE = " + degree);
if ( degree < 0 )
degree = 360 - (-degree);
android.graphics.Matrix matrix = new android.graphics.Matrix();
matrix.postRotate((float) degree, point.x, point.y);
// Polygon polygon;
// Polygon.Builder builder = new Polygon.Builder();
for (int i=0; i<part.getPolygon().getVertex().size(); i++)
{
float[] newPoint = new float[2];
Point p = part.getPolygon().getVertex().get(i);
newPoint[0] = p.x;
newPoint[1] = p.y;
matrix.mapPoints(newPoint);
part.getPolygon().getVertex().remove(i);
part.getPolygon().getVertex().add(i, new Point(newPoint[0], newPoint[1]));
}
previous = new Point(event.getX(), event.getY());
previous = camera.getMapPoint(previous);
}
else if (event.getActionMasked() == MotionEvent.ACTION_UP)
{
previous = null;
isSelected = false;
}
If you want to find angle between vectors (point-previous) and (point-now), use:
Math.atan2((now.x - point.x)*(previous.y - point.y) -
(now.y - point.y)*(previous.x - point.x),
(now.x - point.x)*(now.y - point.y) -
(previous.x - point.x)*(previous.y - point.y))
(This is atan2(vectorproduct, scalarproduct))
You may also use
angle = atan2(now.y-point.y, now.y-point.y)-
atan2(previous.y-point.y, previous.x-point.x);
Related
Thanks in advance for your help first.
I have found so many examples using Gyroscope. But I couldn't find adequate one for me.
I'd like to make a simple quiz game that do actions when I tilt VM to 90 degrees forward and backward. Many examples said I might use "pitch" value of Gyroscope. Could you give some advices for me??
I have done a similar thing where i need draw a rectangle with includes nearby places and must point it to the place and show details.
public void onSensorChanged(SensorEvent event) {
final Handler handler = new Handler();
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
mAcceleromterReading =
SensorUtilities.filterSensors(event.values, mAcceleromterReading);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
mMagnetometerReading =
SensorUtilities.filterSensors(event.values, mMagnetometerReading);
break;
float[] orientation =
SensorUtilities.computeDeviceOrientation(mAcceleromterReading, mMagnetometerReading);
if (orientation != null) {
float azimuth = (float) Math.toDegrees(orientation[0]);
if (azimuth < 0) {
azimuth += 360f;
}
// Convert pitch and roll from radians to degrees
float pitch = (float) Math.toDegrees(orientation[1]);
float roll = (float) Math.toDegrees(orientation[2]);
if (abs(pitch - pitchPrev) > PITCH_THRESHOLD && abs(roll - rollPrev) > ROLL_THRESHOLD
&& abs(azimuth - azimuthPrev) > AZIMUTH_THRESHOLD) { // && abs(roll - rollPrev) > rollThreshold
if (DashplexManager.getInstance().mlocation != null) {
mOverlayDisplayView.setHorizontalFOV(mPreview.getHorizontalFOV());
mOverlayDisplayView.setVerticalFOV(mPreview.getVerticalFOV());
mOverlayDisplayView.setAzimuth(azimuth);
mOverlayDisplayView.setPitch(pitch);
mOverlayDisplayView.setRoll(roll);
// Update the OverlayDisplayView to red raw when sensor dataLogin changes,
// redrawing only when the camera is not pointing straight up or down
if (pitch <= 75 && pitch >= -75) {
//Log.d("issueAR", "invalidate: ");
mOverlayDisplayView.invalidate();
}
}
pitchPrev = pitch;
rollPrev = roll;
azimuthPrev = azimuth;
}
}
computeDeviceOrientation method
public static float[] computeDeviceOrientation(float[] accelerometerReading, float[] magnetometerReading) {
if (accelerometerReading == null || magnetometerReading == null) {
return null;
}
final float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading);
// Remap the coordinates with the camera pointing along the Y axis.
// This way, portrait and landscape orientation return the same azimuth to magnetic north.
final float cameraRotationMatrix[] = new float[9];
SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Z, cameraRotationMatrix);
final float[] orientationAngles = new float[3];
SensorManager.getOrientation(cameraRotationMatrix, orientationAngles);
// Return a float array containing [azimuth, pitch, roll]
return orientationAngles;
}
onDraw method
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Log.d("issueAR", "onDraw: ");
// Log.d("issueAR", "mVerticalFOV: "+mVerticalFOV+" "+"mHorizontalFOV"+mHorizontalFOV);
// Get the viewports only once
if (!mGotViewports && mVerticalFOV > 0 && mHorizontalFOV > 0) {
mViewportHeight = canvas.getHeight() / mVerticalFOV;
mViewportWidth = canvas.getWidth() / mHorizontalFOV;
mGotViewports = true;
//Log.d("onDraw", "mViewportHeight: " + mViewportHeight);
}
if (!mGotViewports) {
return;
}
// Set the paints that remain constant only once
if (!mSetPaints) {
mTextPaint.setTextAlign(Paint.Align.LEFT);
mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.canvas_text_size));
mTextPaint.setColor(Color.WHITE);
mOutlinePaint.setStyle(Paint.Style.STROKE);
mOutlinePaint.setStrokeWidth(mOutline);
mBubblePaint.setStyle(Paint.Style.FILL);
mSetPaints = true;
}
// Center of view
float x = canvas.getWidth() / 2;
float y = canvas.getHeight() / 2;
/*
* Uncomment line below to allow rotation of display around the center point
* based on the roll. However, this "feature" is not very intuitive, and requires
* locking device orientation to portrait or changes the sensor rotation matrix
* on device rotation. It's really quite a nightmare.
*/
//canvas.rotate((0.0f - mRoll), x, y);
float dy = mPitch * mViewportHeight;
if (mNearbyPlaces != null) {
//Log.d("OverlayDisplayView", "mNearbyPlaces: "+mNearbyPlaces.size());
// Iterate backwards to draw more distant places first
for (int i = mNearbyPlaces.size() - 1; i >= 0; i--) {
NearbyPlace nearbyPlace = mNearbyPlaces.get(i);
float xDegreesToTarget = mAzimuth - nearbyPlace.getBearingToPlace();
float dx = mViewportWidth * xDegreesToTarget;
float iconX = x - dx;
float iconY = y - dy;
if (isOverlapping(iconX, iconX).isOverlapped()) {
PointF point = calculateNewXY(new PointF(iconX, iconY + mViewportHeight));
iconX = point.x;
iconY = point.y;
}
nearbyPlace.setIconX(iconX);
nearbyPlace.setIconY(iconY);
Bitmap icon = getIcon(nearbyPlace.getIcon_id());
float width = icon.getWidth() + mTextPaint.measureText(nearbyPlace.getName()) + mMargin;
RectF recf=new RectF(iconX, iconY, width, icon.getHeight());
nearbyPlace.setRect(recf);
float angleToTarget = xDegreesToTarget;
if (xDegreesToTarget < 0) {
angleToTarget = 360 + xDegreesToTarget;
}
if (angleToTarget >= 0 && angleToTarget < 90) {
nearbyPlace.setQuadrant(1);
mQuad1Places.add(nearbyPlace);
} else if (angleToTarget >= 90 && angleToTarget < 180) {
nearbyPlace.setQuadrant(2);
mQuad2Places.add(nearbyPlace);
} else if (angleToTarget >= 180 && angleToTarget < 270) {
nearbyPlace.setQuadrant(3);
mQuad3Places.add(nearbyPlace);
} else {
nearbyPlace.setQuadrant(4);
mQuad4Places.add(nearbyPlace);
}
//Log.d("TAG", " - X: " + iconX + " y: " + iconY + " angle: " + angleToTarget + " display: " + nearbyPlace.getIcon_id());
}
drawQuadrant(mQuad1Places, canvas);
drawQuadrant(mQuad2Places, canvas);
drawQuadrant(mQuad3Places, canvas);
drawQuadrant(mQuad4Places, canvas);
}
}
It doesnot contain full code, but you may understand how pitch and azimuth with roll is used.. Best of luck
I have created custom image view for remove a selected part from bitmap images.
There are operation for select area to get rid from current bitmap by a path has a collection of points.
Here it is code snippet :
for (int i = points.size() - 2; i < points.size(); i++) {
if (i >= 0) {
Point point = points.get(i);
if (i == 0) {
Point next = points.get(i + 1);
point.dx = ((next.x - point.x) / 3);
point.dy = ((next.y - point.y) / 3);
} else if (i == points.size() - 1) {
Point prev = points.get(i - 1);
point.dx = ((point.x - prev.x) / 3);
point.dy = ((point.y - prev.y) / 3);
} else {
Point next = points.get(i + 1);
Point prev = points.get(i - 1);
point.dx = ((next.x - prev.x) / 3);
point.dy = ((next.y - prev.y) / 3);
}
}
}
path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x - point.dx,
point.y - point.dy, point.x, point.y);
paramCanvas.drawPath(path, paint);
Look at this output:
I used clip path to get crop this part but this not working for me.
I am getting stuck to clip that selected part so can you help me out to solve this thing.
I would greatly appreciated any help. Thanks
I want the user to be able to drag the edges of a square around the canvas. With my current solution it works but has glitches, sometimes an edge cannot be selected. Is there a clean way to tell if a line has been clicked (e.g. passes through a coordinate)? This is how I'm currently testing:
// check edge pressed, edge is the line between to
// coords e.g. (i) & (i = 1)
for (int i = 0; i < coords.size(); i++) {
p1 = coords.get(i);
if ((i + 1) > (coords.size() - 1)) p2 = coords.get(0);
else p2 = coords.get(i + 1);
// is this the line pressed
if (p1.x <= event.getX() + 5 && event.getX() - 5 <= p2.x && p1.y <= event.getY() + 5 && event.getY() - 5 <= p2.y) {
// points found, set to non temp
// variable for use in ACTION_MOVE
point1 = p1;
point2 = p2;
break;
} else if (p1.x >= event.getX() + 5 && event.getX() - 5 >= p2.x && p1.y >= event.getY() + 5 && event.getY() - 5 >= p2.y) {
// points found, set to non temp
// variable for use in ACTION_MOVE
point1 = p1;
point2 = p2;
break;
}
}
The code bellow //is this the line pressed is the most important and also most likely the issue. The +5 and -5 are used to give the use a larger area to click on.
Here is the whole on click event:
public void EditEdge() {
//TODO this works like shit
// Detect the two coordinates along the edge pressed and drag
// them
scene.setOnTouchListener(new View.OnTouchListener() {
private int startX;
private int startY;
private Point point1 = new Point(0, 0);
private Point point2 = new Point(0, 0);
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
startY = (int) event.getY();
Point p1;
Point p2;
// check edge pressed, edge is the line between to
// coords e.g. (i) & (i = 1)
for (int i = 0; i < coords.size(); i++) {
p1 = coords.get(i);
if ((i + 1) > (coords.size() - 1)) p2 = coords.get(0);
else p2 = coords.get(i + 1);
// is this the line pressed
if (p1.x <= event.getX() + 5 && event.getX() - 5 <= p2.x && p1.y <= event.getY() + 5 && event.getY() - 5 <= p2.y) {
// points found, set to non temp
// variable for use in ACTION_MOVE
point1 = p1;
point2 = p2;
break;
} else if (p1.x >= event.getX() + 5 && event.getX() - 5 >= p2.x && p1.y >= event.getY() + 5 && event.getY() - 5 >= p2.y) {
// points found, set to non temp
// variable for use in ACTION_MOVE
point1 = p1;
point2 = p2;
break;
}
}
break;
case MotionEvent.ACTION_UP:
point1 = new Point(0, 0);
point2 = new Point(0, 0);
// scene.setOnTouchListener(scene.editModeOnTouchListener);
break;
case MotionEvent.ACTION_MOVE:
for (Point p: new Point[] {
point1, point2
}) {
int modX = (int)(p.x + (event.getX() - startX));
int modY = (int)(p.y + (event.getY() - startY));
p.set(modX, modY);
}
SetCoords(coords);
startX = (int) event.getX();
startY = (int) event.getY();
break;
default:
return false;
}
return true;
}
});
}
So is there a easier way to tell is a line is clicked/ passes through a point or is that not the issue?
Thanks
use the line equation y = mx + b to find out if the point is on a line
float EPSILON = 0.001f;
public boolean isPointOnLine(Point linePointA, Point linePointB, Point point) {
float m = (linePointB.y - linePointA.y) / (linePointB.x - linePointA.x);
float b = linePointA.y - m * linePointA.x;
return Math.abs(point.y - (m*point.x+b)) < EPSILON);
}
Great piece of code by #tyczj !
I added a use-case to handle vertical lines, which gives me the following code fragment:
public boolean isPointOnLine(PointF lineStaPt, PointF lineEndPt, PointF point) {
final float EPSILON = 0.001f;
if (Math.abs(staPt.x - endPt.x) < EPSILON) {
// We've a vertical line, thus check only the x-value of the point.
return (Math.abs(point.x - lineStaPt.x) < EPSILON);
} else {
float m = (lineEndPt.y - lineStaPt.y) / (lineEndPt.x - lineStaPt.x);
float b = lineStaPt.y - m * lineStaPt.x;
return (Math.abs(point.y - (m * point.x + b)) < EPSILON);
}
}
Also a piece of code to check if a point lies on a line-segment:
public boolean isPointOnLineSegment(PointF staPt, PointF endPt, PointF point) {
final float EPSILON = 0.001f;
if (isPointOnLine(staPt, endPt, point)) {
// Create lineSegment bounding-box.
RectF lb = new RectF(staPt.x, staPt.y, endPt.x, endPt.y);
// Extend bounds with epsilon.
RectF bounds = new RectF(lb.left - EPSILON, lb.top - EPSILON, lb.right + EPSILON, lb.bottom + EPSILON);
// Check if point is contained within lineSegment-bounds.
return bounds.contains(point.x, point.y);
}
return false;
}
You could define 8 Rect to check against - the 4 sides and 4 corners (so you can move 2 edges at once). The lines of the edge should have a width for the touchable area.
Define a Point centred on your touch event, there are then methods for checking if a rect contains a point.
problem on calculation of x coordinate for plotting on iPhone screen.When points are within the range of 300 meter we are getting all the point of interest closer even-though In actual they are spread.I have even changed the width of the viewPort from 0.5 to 0.17(In degrees converted 28.647889757 to 10.0).Can anyone suggest such that every points of interest are properly placed with respect to the actual position.
The standard way(Mixare,ARToolkit) of calculating points on AR is
Calculate using ARKit
double pointAzimuth = coordinate.coordinateAzimuth;
//our x numbers are left based.
double leftAzimuth = self.currentCoordinate.coordinateAzimuth - VIEWPORT_WIDTH_RADIANS / 2.0;
if (leftAzimuth < 0.0) {
leftAzimuth = 2 * M_PI + leftAzimuth;
}
if (pointAzimuth < leftAzimuth) {
//it's past the 0 point.
point.x = ((2 * M_PI - leftAzimuth + pointAzimuth) / VIEWPORT_WIDTH_RADIANS) * 480.0;
} else {
point.x = ((pointAzimuth - leftAzimuth) / VIEWPORT_WIDTH_RADIANS) * 480.0;
}
IN Mixare:
CGPoint point;
CGRect viewBounds = self.overlayView.bounds;
//NSLog(#"pointForCoordinate: viewBounds.size.width = %.3f, height = %.3f", viewBounds.size.width, viewBounds.size.height );
double currentAzimuth = self.currentCoordinate.coordinateAzimuth;
double pointAzimuth = coordinate.coordinateAzimuth;
//NSLog(#"pointForCoordinate: location = %#, pointAzimuth = %.3f, pointInclination = %.3f, currentAzimuth = %.3f", coordinate.coordinateTitle, point.x, point.y, radiansToDegrees(pointAzimuth), radiansToDegrees(currentAzimuth), radiansToDegrees(pointInclination) );
double deltaAzimuth = [self deltaAzimuthForCoordinate:coordinate];
BOOL isBetweenNorth = [self isNorthForCoordinate:coordinate];
//NSLog(#"pointForCoordinate: (1) currentAzimuth = %.3f, pointAzimuth = %.3f, isNorth = %d", radiansToDegrees(currentAzimuth), radiansToDegrees(pointAzimuth), isBetweenNorth );
// NSLog(#"pointForCoordinate: deltaAzimuth = %.3f", radiansToDegrees(deltaAzimuth));
//NSLog(#"pointForCoordinate: (2) currentAzimuth = %.3f, pointAzimuth = %.3f, isNorth = %d", radiansToDegrees(currentAzimuth), radiansToDegrees(pointAzimuth), isBetweenNorth );
if ((pointAzimuth > currentAzimuth && !isBetweenNorth) ||
(currentAzimuth > degreesToRadians(360-self.viewRange) &&
pointAzimuth < degreesToRadians(self.viewRange))) {
// Right side of Azimuth
point.x = (viewBounds.size.width / 2) + ((deltaAzimuth / degreesToRadians(1)) * 12);
} else {
// Left side of Azimuth
point.x = (viewBounds.size.width / 2) - ((deltaAzimuth / degreesToRadians(1)) * 12);
}
I wanted to draw a rectangle in android, but not just by specifying the left, top, right and bottom. What I have are 4 vertex coordinates. The rectangle is not horizontal but oblique, so something like the image of the rectangle below:
I've been trying to see if I can use a matrix to perform some kind of rotation or use canvas.rotate(), but I'm still not clear how to do it. Can somebody help me with how to draw such a rectangle?
I'd be interested in seeing somebody else's solution to this problem, but if there isn't an easier way, here's how I implemented it the hard way:
public void drawLineThick(GL10 gl, int thickness, FloatBuffer whichBuffer)
{
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
final float x0 = whichBuffer.get(0);
final float x1 = whichBuffer.get(2);
final float y0 = whichBuffer.get(1);
final float y1 = whichBuffer.get(3);
boolean slopeZeroCase = false;
boolean undefinedSlopeCase = false;
boolean slopeOneCase = false;
boolean slopeNegOneCase = false;
boolean slopeSmall = false;
boolean slopeBig = false;
float boxThickness = thickness * .001f;
//Slope (y2-y1)/(x2-x1)
float m = 0.0f;
//b parameter of y=mx+b formula, b=y-mx
float b = 0.0f;
//Special cases for handling when the slope is zero, undefined
//both (line of length zero), one, or negative one.
if (y1 - y0 == 0)
{
slopeZeroCase = true;
}
if (x1 - x0 == 0)
{
undefinedSlopeCase = true;
}
//If the slope isn't going to be zero or undefined, it's safe to
//actually try to calculate it so that we don't have a "divide by zero"
//by accident
if (slopeZeroCase == false && undefinedSlopeCase == false)
{
m = ((y1 - y0)/(x1 - x0));
b = (y0 - (m*x0));
}
if ( m == 1.0f)
{
slopeOneCase = true;
}
if (m == -1.0f)
{
slopeNegOneCase = true;
}
if ((m > 0 && m < 1) || (m < 0 && m > -1))
{
slopeSmall = true;
}
else
{
slopeBig = true;
}
//float tempFloat[] = new float[8];
//Normal line where there is a slope involved
if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false && slopeSmall == true)
{
/**
* Given a sloped line, in order to make it, "thicker",
* one must offset the original line by + and - the
* thickness, in essence creating a box. The formula
* for the points of a given box below (in the direction drawn)
* will be:
*
* p0 p1
* *----------*
* | |
* | |
* | |
* | |
* *----------*
* p3 p2
*
*/
//p1, x
tempFloat[0] = x0;
//p1, y
tempFloat[1] = y0 + boxThickness;
//p2, x
tempFloat[2] = x1;
//p2, y
tempFloat[3] = y1 + boxThickness;
//p3, x
tempFloat[4] = x1;
//p3, y
tempFloat[5] = y1 - boxThickness;
//p4, x
tempFloat[6] = x0;
//p4, y
tempFloat[7] = y0 - boxThickness;
}
else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false && slopeSmall == false)
{
/**
* Given a sloped line, in order to make it, "thicker",
* one must offset the original line by + and - the
* thickness, in essence creating a box. The formula
* for the points of a given box below (in the direction drawn)
* will be:
*
*
*
* p0 p1
* *----------*
* | |
* | |
* | |
* | |
* *----------*
* p3 p2
*
*/
//p1, x
tempFloat[0] = x0 + boxThickness;
//p1, y
tempFloat[1] = y0;
//p2, x
tempFloat[2] = x1 + boxThickness;
//p2, y
tempFloat[3] = y1;
//p3, x
tempFloat[4] = x1 - boxThickness;
//p3, y
tempFloat[5] = y1;
//p4, x
tempFloat[6] = x0 - boxThickness;
//p4, y
tempFloat[7] = y0;
}
//Horizontal line case, only need to change the y to be +- thickness
else if (slopeZeroCase == true && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == false)
{
//Log.i("draw", "Horizontal");
//p1, x
tempFloat[0] = x0;
//p1, y
tempFloat[1] = y0 + boxThickness;
//p2, x
tempFloat[2] = x1;
//p2, y
tempFloat[3] = y1 + boxThickness;
//p3, x
tempFloat[4] = x1;
//p3, y
tempFloat[5] = y1 - boxThickness;
//p4, x
tempFloat[6] = x0;
//p4, y
tempFloat[7] = y0 - boxThickness;
}
//Vertical line case, only need to change the x to be +- thickness
else if (slopeZeroCase == false && undefinedSlopeCase == true && slopeOneCase == false && slopeNegOneCase == false)
{
//Log.i("draw", "Vertical");
//p1, x
tempFloat[0] = x0 + boxThickness;
//p1, y
tempFloat[1] = y0;
//p2, x
tempFloat[2] = x1 + boxThickness;
//p2, y
tempFloat[3] = y1;
//p3, x
tempFloat[4] = x1 - boxThickness;
//p3, y
tempFloat[5] = y1;
//p4, x
tempFloat[6] = x0 - boxThickness;
//p4, y
tempFloat[7] = y0;
}
//Case where slope = 1
else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == true && slopeNegOneCase == false)
{
//Log.i("draw", "OneSlope");
//p1, x
tempFloat[0] = y0 - boxThickness;
//p1, y
tempFloat[1] = x0 + boxThickness;
//p2, x
tempFloat[2] = y1 - boxThickness;
//p2, y
tempFloat[3] = x1 + boxThickness;
//p3, x
tempFloat[4] = y1 + boxThickness;
//p3, y
tempFloat[5] = x1 - boxThickness;
//p4, x
tempFloat[6] = y0 + boxThickness;
//p4, y
tempFloat[7] = x0 - boxThickness;
}
//Case where slope = -1
else if (slopeZeroCase == false && undefinedSlopeCase == false && slopeOneCase == false && slopeNegOneCase == true)
{
Log.i("draw", "OneSlope");
//p1, x
tempFloat[0] = -y0 + boxThickness;
//p1, y
tempFloat[1] = -x0 + boxThickness;
//p2, x
tempFloat[2] = -y1 + boxThickness;
//p2, y
tempFloat[3] = -x1 + boxThickness;
//p3, x
tempFloat[4] = -y1 - boxThickness;
//p3, y
tempFloat[5] = -x1 - boxThickness;
//p4, x
tempFloat[6] = -y0 - boxThickness;
//p4, y
tempFloat[7] = -x0 - boxThickness;
}
//Allocate the wrapped buffers that OpenGL ES uses for drawing, buffers changed to
//be allocated at class scope so that they're not re-allocated every time this
//algorithm is run
//ByteBuffer tempBoxByteBuffer = ByteBuffer.allocateDirect(tempFloat.length * 4);
//tempBoxByteBuffer.order(ByteOrder.nativeOrder());
//FloatBuffer boxFloatBuffer = tempBoxByteBuffer.asFloatBuffer();
boxFloatBuffer.put(tempFloat);
boxFloatBuffer.position(0);
//Draw triangles using points p0, p1, and p2 for the first, and
//p0, p3, and p2 for the second, filling in between. See box
//above for diagram of points. Indices also changed to be allocated at class scope
//short indices[] = {0, 1, 2, 0, 3, 2};
//ByteBuffer tempIndiceBuffer = ByteBuffer.allocateDirect(indices.length * 2);
//tempIndiceBuffer.order(ByteOrder.nativeOrder());
//ShortBuffer indiceBuffer = tempIndiceBuffer.asShortBuffer();
//indiceBuffer.put(indices);
//indiceBuffer.position(0);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, boxFloatBuffer);
//gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 2);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indiceBuffer);
}
This particular implementation was done so that I could have a filled-in box, which is not a default OpenGL ES capability. What I did, instead, was draw two triangles. The math includes several special cases, a zero slope, a one slope, an undefined slope, a slope is greater than 0 but less than one or less than zero but greater than negative one case, or a slope is greater than one or less than negative one case. All you have to do is draw a line loop instead of a triangle between each set of points, and you'll have a non-filled box.
workaround :
instead of drawing rectangle draw a line but set stroke width for paint.