I need help getting the object coordinates during an interaction. The setting is as follows: I have a geometric object along with coordinate system displayed. I attach a tool so that the user can click at points outside the geometric object. The geometric object gets reshaped using these points.
To get accurate reshaping, the points selected by the user need to be captured by the interaction tool accurately. In this case, the coordinate system allows the user to identify the point accurately. The tool needs to return the same point to the reshaping algorithm.
I have a problem capturing this point ( in object coordinates - in coordinate system coordinates displayed). In my application, I use the AddPointsExample tutorial. I attach the code below. I tried
clicking on two points: (8, 2) and ( 20, 10). The application recognized them as (19.13.., 8.15...,..) and (20.05.., 8.66...,...). The same happened with other points.
I think I am not converting correctly the world coordinates into object coordinates. How do I get back (8, 2) and (20, 10) in the above example?
I shall really appreciate the help.
Code: Select all
public class ToolContextTest1 {
private ArrayList<Point3D> points;
private DefaultGeometryShader defaultGeometryShader;
private String label;
private double[][] controlPoints;
// IndexedLineSetFactory lsf = new IndexedLineSetFactory();
double offset = 5;
private SceneGraphComponent curveSGC;
private SceneGraphComponent controlSGC;
private double[][] curvePoints;
private boolean mouseClicked = false;
private ArrayList<Point3D> points2;
private double[] startPoint;
private double[] endPoint;
public static void main(String[] args) {
ToolContextTest1 example = new ToolContextTest1();
}
public ToolContextTest1() {
SceneGraphComponent world = SceneGraphUtility
.createFullSceneGraphComponent();
world.addTool(new AbstractTool() {
{
addCurrentSlot(InputSlot.SHIFT_LEFT_BUTTON, "add a new point");
}
public void perform(ToolContext tc) {
System.out.println("Entering perform method");
if (!tc.getAxisState(InputSlot.SHIFT_LEFT_BUTTON).isPressed())
return;
// determine the pointer transformation:
// translation is the mouse pointer on the near clipping plane
// z-axis is the direction of the mouse ray out of the screen
// for a 6DOF input device, it is the position/orientation of
// the device
Matrix m = new Matrix(
tc
.getTransformationMatrix(InputSlot.POINTER_TRANSFORMATION));
// we compute the coordinates of the new point in world
// coordinates
double[] foot = m.getColumn(3);
double[] dir = m.getColumn(2);
double[] offset = Rn.times(null, -5, dir);
double[] newPoint = Rn.add(null, foot, offset);
System.out.println("New Point is: [" + newPoint[0] + ", "
+ newPoint[1] + ", " + newPoint[2] + "]");
// now we transform the world coordinates to the coordinate
// system of the tool component
if (!mouseClicked) {
startPoint = ToolUtility.worldToLocal(tc, newPoint);
points.add(new Point3D(startPoint));
System.out
.println("Start Point is: [" + startPoint[0] + ", "
+ startPoint[1] + ", " + startPoint[2]
+ "]");
mouseClicked = true;
} else {
endPoint = ToolUtility.worldToLocal(tc, newPoint);
points2.add(new Point3D(endPoint));
System.out.println("End Point is: [" + endPoint[0] + ", "
+ endPoint[1] + ", " + endPoint[2] + "]");
attachGeometry();
}
}
});
points = generatePoints();
curvePoints = convertToArray(generatePoints());
points2 = generateControlPoints();
controlPoints = convertToArray(generateControlPoints());
createCCP_SGC(world);
setUpCoordinateSystem(world);
JRViewer.display(world);
}
public void createCCP_SGC(SceneGraphComponent sgc) {
curveSGC = SceneGraphUtility.createFullSceneGraphComponent("Curve");
controlSGC = SceneGraphUtility.createFullSceneGraphComponent("Control");
sgc.addChild(curveSGC);
curveSGC.addChild(controlSGC);
attachGeometry();
}
public void attachGeometry() {
createCurveGeometry(curveSGC, Color.BLUE, convertToArray(points));
createCurveGeometry(controlSGC, Color.GRAY, convertToArray(points2));
}
public void createCurveGeometry(SceneGraphComponent sgc, Color color,
double[][] points) {
IndexedLineSetFactory factory = new IndexedLineSetFactory();
double[][] vertices = points;
int labelPoint = points.length / 2;
setUpLabelForCurve(sgc, color, vertices, labelPoint, 0);
int[][] edgeIndices = createEdgeIndices(vertices);
factory.setVertexCount(vertices.length);
factory.setVertexCoordinates(vertices);
factory.setEdgeCount(edgeIndices.length);
factory.setEdgeIndices(edgeIndices);
factory.update();
sgc.setGeometry(factory.getGeometry());
setUpCurveAppearance(sgc, color);
}
public void setUpCurveAppearance(SceneGraphComponent sgc, Color color) {
// set up the line shader
Appearance ap = sgc.getAppearance();
defaultGeometryShader = ShaderUtility.createDefaultGeometryShader(ap,
true);
defaultGeometryShader.setShowPoints(false);
defaultGeometryShader.setShowLines(true);
RenderingHintsShader rhs = ShaderUtility
.createDefaultRenderingHintsShader(ap, true);
DefaultLineShader dls = (DefaultLineShader) defaultGeometryShader
.createLineShader("default");
dls.setTubeDraw(false);
dls.setLineWidth(3.0);
dls.setDiffuseColor(color);
}
public int[][] createEdgeIndices(double[][] points) {
int[][] edges = new int[points.length - 1][2];
for (int i = 0; i < points.length - 1; i++) {
edges[i][0] = i;
edges[i][1] = i + 1;
}
return edges;
}
public double[][] convertToArray(ArrayList<Point3D> points) {
double[][] newPoints = new double[points.size()][3];
for (int i = 0; i < points.size(); i++) {
double[] pt = points.get(i).getPoint();
newPoints[i] = new double[] { pt[0], pt[1], pt[2] };
System.out.println("Point: (" + newPoints[i][0] + ", "
+ newPoints[i][1] + ", " + newPoints[i][2] + ")");
}
return newPoints;
}
public double[][] normalizePoints(double[][] points) {
double largestValue = findLargestValue(points);
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points[i].length; j++) {
points[i][j] = points[i][j] / largestValue;
}
}
return points;
}
public double findLargestValue(double[][] points) {
double value = -1000.0;
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points[i].length; j++) {
if (value < points[i][j])
value = points[i][j];
}
}
return value;
}
public ArrayList<Point3D> generatePoints() {
ArrayList<Point3D> points = new ArrayList<Point3D>();
Point3D point1 = new Point3D();
point1.setPoint(new double[] { 0.0f, 0.0f, 0.0f });
points.add(point1);
Point3D point2 = new Point3D();
point2.setPoint(new double[] { 2.0f, 2.0f, 0.0f });
points.add(point2);
Point3D point3 = new Point3D();
point3.setPoint(new double[] { 5.0f, 9.0f, 0.0f });
points.add(point3);
Point3D point4 = new Point3D();
point4.setPoint(new double[] { 10.0f, 10.0f, 0.0f });
points.add(point4);
Point3D point5 = new Point3D();
point5.setPoint(new double[] { 12.0f, 8.0f, 0.0f });
points.add(point5);
Point3D point6 = new Point3D();
point6.setPoint(new double[] { 18.0f, 2.0f, 0.0f });
points.add(point6);
Point3D point7 = new Point3D();
point7.setPoint(new double[] { 20.0f, 0.0f, 0.0f });
points.add(point7);
Point3D point8 = new Point3D();
point8.setPoint(new double[] { 22.0f, 2.0f, 0.0f });
points.add(point8);
Point3D point9 = new Point3D();
point9.setPoint(new double[] { 25.0f, 9.0f, 0.0f });
points.add(point9);
Point3D point10 = new Point3D();
point10.setPoint(new double[] { 30.0f, 10.0f, 0.0f });
points.add(point10);
Point3D point11 = new Point3D();
point11.setPoint(new double[] { 32.0f, 8.0f, 0.0f });
points.add(point11);
Point3D point12 = new Point3D();
point12.setPoint(new double[] { 38.0f, 2.0f, 0.0f });
points.add(point12);
Point3D point13 = new Point3D();
point13.setPoint(new double[] { 40.0f, 0.0f, 0.0f });
points.add(point13);
return points;
}
public ArrayList<Point3D> generateControlPoints() {
ArrayList<Point3D> points = new ArrayList<Point3D>();
Point3D point1 = new Point3D();
point1.setPoint(new double[] { 0.0, 0.0, 0.0 });
points.add(point1);
Point3D point2 = new Point3D();
point2.setPoint(new double[] { 2.0, 5.0, 0.0 });
points.add(point2);
Point3D point3 = new Point3D();
point3.setPoint(new double[] { 5.0, 14.0, 0.0 });
points.add(point3);
Point3D point4 = new Point3D();
point4.setPoint(new double[] { 10.0, 17.0, 0.0 });
points.add(point4);
Point3D point5 = new Point3D();
point5.setPoint(new double[] { 12.0, 15.0, 0.0 });
points.add(point5);
Point3D point6 = new Point3D();
point6.setPoint(new double[] { 18.0, 7.0, 0.0 });
points.add(point6);
Point3D point7 = new Point3D();
point7.setPoint(new double[] { 20.0, 5.0, 0.0 });
points.add(point7);
Point3D point8 = new Point3D();
point8.setPoint(new double[] { 22.0, 8.0, 0.0 });
points.add(point8);
Point3D point9 = new Point3D();
point9.setPoint(new double[] { 25.0, 16.0, 0.0 });
points.add(point9);
Point3D point10 = new Point3D();
point10.setPoint(new double[] { 30.0, 15.0, 0.0 });
points.add(point10);
Point3D point11 = new Point3D();
point11.setPoint(new double[] { 32.0, 14.0, 0.0 });
points.add(point11);
Point3D point12 = new Point3D();
point12.setPoint(new double[] { 38.0, 7.0, 0.0 });
points.add(point12);
Point3D point13 = new Point3D();
point13.setPoint(new double[] { 40.0, 0.0, 0.0 });
points.add(point13);
return points;
}
class Point3D {
public double[] point;
public Point3D(double[] point) {
this.point = point;
}
public Point3D() {
// ToDo
}
public double[] getPoint() {
return point;
}
public void setPoint(double[] point) {
this.point = point;
}
}
public void setUpPlots(double[][] points, double[][] controlPoints,
String label) {
// this.label = label;
// curvePoints = points;
// this.controlPoints = controlPoints;
// colors = createColorList(numberCurves);
// curveType = 3;
SceneGraphComponent world = SceneGraphUtility
.createFullSceneGraphComponent("world");
world.getAppearance().setAttribute(LINE_SHADER + "." + SMOOTH_SHADING,
true);
world.getAppearance().setAttribute(SMOOTH_SHADING, false);
// setUpCurves(world);
// createCoordinateSystem(world);
setUpCoordinateSystem(world);
JRViewer.display(world);
}
public void setUpCoordinateSystem(SceneGraphComponent component) {
// create coordinate system
final CoordinateSystemFactory coords = new CoordinateSystemFactory(
component);
// SET PROPERTIES:
double axisScale = 2.0;
Font font = new Font("TimesRoman", Font.PLAIN, 80);
coords.setAxisScale(axisScale);
coords.setLabelScale(0.01);
// coords.showBoxArrows(true);
coords.showAxesArrows(true);
coords.showLabels(true);
// coords.setColor(Color.RED);
// coords.setGridColor(Color.GRAY);
coords.setLabelColor(Color.DARK_GRAY);
coords.setLabelFont(font);
coords.setColor(Color.BLUE);
// display axes/box/grid
coords.showAxes(true);
// coords.showBox(true);
coords.showGrid(false);
// beautify box
coords.beautify(true);
}
public void drawCurveWithLabel(double[][] verts, double[][] contPts,
int index, SceneGraphComponent sgc, Color color) {
SceneGraphComponent child1 = SceneGraphUtility
.createFullSceneGraphComponent("child" + index);
sgc.addChild(child1);
int numPoints = verts.length;
int[][] edges = createEdgeIndices(verts);
// double[][] edgeColors = createEdgeColors(edges.length, index);
int labelPoint = numPoints / 2;
setUpLabelForCurve(child1, color, verts, labelPoint, index);
// set up the indexed line set for this example
IndexedLineSetFactory lsf = new IndexedLineSetFactory();
lsf.setVertexCount(numPoints);
lsf.setVertexCoordinates(verts);
lsf.setVertexNormals(verts); // outward pointing normals for lighting
// enabled
lsf.setEdgeCount(edges.length);
lsf.setEdgeIndices(edges);
lsf.update();
IndexedLineSet ils = lsf.getIndexedLineSet();
child1.setGeometry(ils);
// set up the line shader
Appearance ap = child1.getAppearance();
defaultGeometryShader = ShaderUtility.createDefaultGeometryShader(ap,
true);
defaultGeometryShader.setShowPoints(false);
defaultGeometryShader.setShowLines(true);
RenderingHintsShader rhs = ShaderUtility
.createDefaultRenderingHintsShader(ap, true);
DefaultLineShader dls = (DefaultLineShader) defaultGeometryShader
.createLineShader("default");
dls.setTubeDraw(false);
dls.setLineWidth(3.0);
dls.setDiffuseColor(color);
// Set up curve for control points
SceneGraphComponent child2 = SceneGraphUtility
.createFullSceneGraphComponent("grandchild" + index);
child1.addChild(child2);
numPoints = contPts.length;
edges = createEdgeIndices(contPts);
// double[][] edgeColors = createEdgeColors(edges.length, index);
labelPoint = numPoints / 2;
setUpLabelForCurve(child2, color, contPts, labelPoint, index);
// set up the indexed line set for this example
lsf = new IndexedLineSetFactory();
lsf.setVertexCount(numPoints);
lsf.setVertexCoordinates(contPts);
lsf.setVertexNormals(contPts); // outward pointing normals for lighting
// enabled
lsf.setEdgeCount(edges.length);
lsf.setEdgeIndices(edges);
lsf.update();
ils = lsf.getIndexedLineSet();
child2.setGeometry(ils);
// set up the line shader
ap = child2.getAppearance();
defaultGeometryShader = ShaderUtility.createDefaultGeometryShader(ap,
true);
defaultGeometryShader.setShowPoints(false);
defaultGeometryShader.setShowLines(true);
rhs = ShaderUtility.createDefaultRenderingHintsShader(ap, true);
dls = (DefaultLineShader) defaultGeometryShader
.createLineShader("default");
dls.setTubeDraw(false);
dls.setLineWidth(2.0);
dls.setDiffuseColor(Color.CYAN);
}
public void setUpLabelForCurve(SceneGraphComponent child, Color color,
double[][] verts, int labelPoint, int index) {
// create the label at the center of the example
Appearance app = setUpLabels(color, new double[] {
verts[labelPoint][0], verts[labelPoint][1],
verts[labelPoint][2] });
SceneGraphComponent labelSGC = SceneGraphUtility
.createFullSceneGraphComponent(label + Integer.toString(index));
PointSetFactory labelFac = new PointSetFactory();
labelFac.setVertexCount(1);
labelFac.setVertexCoordinates(new double[] { verts[labelPoint][0],
verts[labelPoint][1], verts[labelPoint][2] });
labelFac.setVertexLabels(new String[] { label
+ Integer.toString(index + 1) });
labelFac.update();
labelSGC.setGeometry(labelFac.getPointSet());
labelSGC.setAppearance(app);
child.addChild(labelSGC);
}
public Appearance setUpLabels(Color color, double[] offset) {
// each sample gets a numeric label at its geometric center point.
// Prepare the appearance.
Appearance labelAp = new Appearance();
defaultGeometryShader = ShaderUtility.createDefaultGeometryShader(
labelAp, false);
defaultGeometryShader.setShowPoints(true);
DefaultPointShader pointShader = (DefaultPointShader) defaultGeometryShader
.getPointShader();
pointShader.setPointRadius(.0001);
DefaultTextShader pts = (DefaultTextShader) (pointShader)
.getTextShader();
pts.setScale(.01);
pts.setOffset(offset);
pts.setAlignment(SwingConstants.CENTER);
pts.setDiffuseColor(color);
Font font = new Font("TimesRoman", Font.PLAIN, 60);
pts.setFont(font);
return labelAp;
}
}
Karuna