package tansform;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.LineArray;
import javax.media.j3d.LineAttributes;
import javax.media.j3d.Shape3D;
import javax.vecmath.Point3f;
/**
* 将空间中的两点用圆滑直角曲线连接
*
* @author Administrator
*/
public class VisualizeLine {
private Point3f point1;
private Point3f point2;
/** 第一个点连接线的直线部分 */
private Shape3D straightLine1;
/** 第二个点连接线的直线部分 */
private Shape3D straightLine2;
/** 汇集中点的高度增量 */
private float influxPointHeight = 0.2f;
/** 连接两点抛物线的线段数量 */
private int pointCount = 20;
/** 递归深度 */
private int stackDepth = 11;
/** 左曲线递归深度变量记录 */
private int stackLeft = 0;
/** 右曲线递归深度变量记录 */
private int stackRight = 0;
/** 曲线左连线各点集合 */
private ArrayList<Point3f> pointsLeft = new ArrayList<Point3f>();
/** 曲线右连线各点集合 */
private ArrayList<Point3f> pointsRight = new ArrayList<Point3f>();
/** 曲线各点集合 */
private ArrayList<Point3f> points = new ArrayList<Point3f>();
public VisualizeLine(Point3f point1, Point3f point2) {
this.point1 = point1;
this.point2 = point2;
}
/**
* 功能:将两个点用圆角曲线连接
*
* @param lineHeight
* @param bg
*/
public void link(int lineHeight, BranchGroup bg) {
// 计算第一条线的结束点
Point3f p1End = new Point3f(point1.x, 0.2f, point1.z);
pointsLeft.add(p1End);
// 计算第二条线的结束点
Point3f p2End = new Point3f(point2.x, 0.2f, point2.z);
pointsRight.add(p2End);
LineArray line1 = createStraightLine(point1, p1End);
straightLine1 = createLineShape(line1);
bg.addChild(straightLine1);
LineArray line2 = createStraightLine(point2, p2End);
straightLine2 = createLineShape(line2);
bg.addChild(straightLine2);
Shape3D[] arrayShap = createCurveLine(p1End, p2End);
for (int i = 0; i < 2; i++) {
bg.addChild(arrayShap[i]);
}
}
/**
* 生成两点之间的直线
*
* @param pointStart
* 起始点
* @param pointEnd
* 结束点
*/
private LineArray createStraightLine(Point3f pointStart, Point3f pointEnd) {
float vert[] = new float[6];
float color[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
vert[0] = pointStart.x;
vert[1] = pointStart.y;
vert[2] = pointStart.z;
vert[3] = pointEnd.x;
vert[4] = pointEnd.y;
vert[5] = pointEnd.z;
LineArray line = new LineArray(2, LineArray.COORDINATES
| LineArray.COLOR_3);
line.setCoordinates(0, vert);
line.setColors(0, color);
return line;
}
/**
* 功能: 生成连线显示对象
*
* @param line
* LineArray对象
* @return
*/
private Shape3D createLineShape(LineArray line) {
Shape3D shape = new Shape3D();
LineAttributes la = new LineAttributes();
la.setLineWidth(1.0f);
la.setLinePattern(LineAttributes.PATTERN_SOLID);
la.setLineAntialiasingEnable(true);
Appearance ap = new Appearance();
ap.setLineAttributes(la);
shape.setGeometry(line);
shape.setAppearance(ap);
return shape;
}
/**
* 功能: 生成两点垂直于y轴之间的曲线数组,最终各个曲线连接为一个圆滑整曲线
*
* @param pointStart
* 起始点
* @param pointEnd
* 结束点
* @return 左右曲线图形对象数组
*/
private Shape3D[] createCurveLine(Point3f pointStart, Point3f pointEnd) {
// 算出连线起最终汇集点
Point3f p = new Point3f((point1.x + point2.x) / 2.0f,
(pointStart.y + pointEnd.y) / 2.0f + influxPointHeight,
(point1.z + point2.z) / 2.0f);
pointsLeft.add(p);
pointsRight.add(p);
// 生成曲线所需连接点列表
creatLeftCurvePoints(pointStart, p, influxPointHeight);
creatRightCurvePoints(p, pointEnd, influxPointHeight);
// 左右曲线点集合按照y值排序
Collections.sort(pointsLeft, new SortByY());
Collections.sort(pointsRight, new SortByY());
// 转化为lineArray
LineArray lineArrayLeft = tranformData(pointsLeft);
LineArray lineArrayRight = tranformData(pointsRight);
Shape3D shapeCurveLeft = createLineShape(lineArrayLeft);
Shape3D shapeCurveRight = createLineShape(lineArrayRight);
Shape3D[] arrayShape = new Shape3D[2];
arrayShape[0] = shapeCurveLeft;
arrayShape[1] = shapeCurveRight;
return arrayShape;
}
private void createCurvePoints(){
}
private LineArray tranformData(ArrayList<Point3f> points) {
int pointCount = points.size();
LineArray lineArray = new LineArray(pointCount, LineArray.COORDINATES
| LineArray.COLOR_3);
float color[] = new float[pointCount * 3];
float vert[] = new float[pointCount * 3];
for (int i = 0; i < pointCount; i++) {
vert[i * 3] = points.get(i).x;
vert[i * 3 + 1] = points.get(i).y;
vert[i * 3 + 2] = points.get(i).z;
color[i * 3] = 0;
color[i * 3 + 1] = 0;
color[i * 3 + 2] = 0;
}
lineArray.setCoordinates(0, vert);
lineArray.setColors(0, color);
return lineArray;
}
/**
* 获得左曲线连接点集合
*
* @param pointStart
* @param pointEnd
*/
private void creatLeftCurvePoints(Point3f pointStart, Point3f pointEnd,
float influxPointHeightPass) {
float halfInflux = influxPointHeightPass / 2.0f;
if (halfInflux >= influxPointHeight / 32.0f) {
Point3f ps = new Point3f((pointStart.x + pointEnd.x) / 2.0f,
(pointStart.y + pointEnd.y) / 2.0f + halfInflux,
(pointStart.z + pointEnd.z) / 2.0f);
pointsLeft.add(ps);
pointsLeft.add(ps);
// stackLeft++;
creatLeftCurvePoints(pointStart, ps, halfInflux);
creatLeftCurvePoints(ps, pointEnd, halfInflux);
}
}
/**
* 获得右曲线连接点集合
*
* @param pointStart
* @param pointEnd
*/
private void creatRightCurvePoints(Point3f pointStart, Point3f pointEnd,
float influxPointHeight) {
if (stackRight <= stackDepth) {
float halfInflux = influxPointHeight / 2.0f;
Point3f ps = new Point3f((pointStart.x + pointEnd.x) / 2.0f,
(pointStart.y + pointEnd.y) / 2.0f + halfInflux,
(pointStart.z + pointEnd.z) / 2.0f);
pointsRight.add(ps);
pointsRight.add(ps);
stackRight++;
creatRightCurvePoints(ps, pointEnd, halfInflux);
}
}
}
/**
* 根据空间点y值排序
*/
class SortByY implements Comparator<Point3f> {
public int compare(Point3f obj1, Point3f obj2) {
Point3f point1 = obj1;
Point3f point2 = obj2;
if (point1.getY() > point2.getY())
return 1;
else
return 0;
}
}