org.fudaa.dodico.rubar.io.RubarIMAReader Maven / Gradle / Ivy
The newest version!
package org.fudaa.dodico.rubar.io;
import gnu.trove.TIntArrayList;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.fudaa.ctulu.CtuluLibMessage;
import org.fudaa.dodico.ef.EfElement;
import org.fudaa.dodico.ef.EfNode;
import org.fudaa.dodico.ef.EfNodeComparator;
import org.fudaa.dodico.ef.impl.EfGrid;
import org.fudaa.dodico.fortran.FileOpReadCharSimpleAbstract;
/**
* @author CANEL Christophe (Genesis)
*/
public class RubarIMAReader extends FileOpReadCharSimpleAbstract {
private static final EfNodeComparator comparator = new EfNodeComparator();
@Override
protected Object internalRead() {
final int[] fmtLength = new int[]{6, 6};
final int[] fmtNodes = new int[]{10, 10, 10, 10};
final List nodes = new ArrayList();
final List elements = new ArrayList();
final Map nodesIdx = new TreeMap(comparator);
EfGrid grid = null;
try {
while (true) {
in_.readFields(fmtLength);
final int nl = in_.intField(0);
final int nc = in_.intField(1);
final double[][] xs = new double[nl + 1][nc + 1];
final double[][] ys = new double[nl + 1][nc + 1];
in_.readFields(fmtNodes);
xs[0][0] = in_.doubleField(0);
ys[0][0] = in_.doubleField(1);
xs[0][nc] = in_.doubleField(2);
ys[0][nc] = in_.doubleField(3);
in_.readFields(fmtNodes);
xs[nl][nc] = in_.doubleField(0);
ys[nl][nc] = in_.doubleField(1);
xs[nl][0] = in_.doubleField(2);
ys[nl][0] = in_.doubleField(3);
if (((nl != 1) || (nc != 1)) && this.isTriangle(xs, ys)) {
//TODO Voir quoi faire dans ce cas.
} else {
this.fillPts(xs, ys);
final int[][] idxs = this.convertPtsToNodesIndex(xs, ys, nodes, nodesIdx);
this.createElements(idxs, elements);
}
}
} catch (final EOFException e) {
final int nbNodes = nodes.size();
final int nbElements = elements.size();
final EfNode[] nds = new EfNode[nbNodes];
final EfElement[] elts = new EfElement[nbElements];
for (int i = 0; i < nbNodes; i++) {
nds[i] = nodes.get(i);
}
for (int i = 0; i < nbElements; i++) {
elts[i] = elements.get(i);
}
grid = new EfGrid(nds, elts);
if (CtuluLibMessage.DEBUG) {
CtuluLibMessage.debug("Fin du fichier");
}
} catch (final NumberFormatException e) {
analyze_.manageException(e, in_.getLineNumber());
} catch (final IOException e) {
analyze_.manageException(e);
}
return grid;
}
private boolean isTriangle(double[][] xs, double[][] ys) {
return (comparator.compare(xs[0][0], ys[0][0], xs[xs.length - 1][0], ys[ys.length - 1][0]) == 0);
}
private void fillPts(double[][] xs, double[][] ys) {
//Les tableaux contient pour la premi?re dimension des colonnes et pour la deuxi?me
//les cellules, par cons?quent l'on peut r?cup?rer facilement une colonne enti?re,
//mais pas une ligne enti?re.
//Donc on va remplir les valeurs manquantes pour les premi?re et derni?re lignes,
//ainsi apr?s on boucle sur chaque chaque et on calcul les points manquants.
final int lastLineIdx = xs[0].length - 1;
final int nbColumns = xs.length;
final double[] lineX = new double[nbColumns];
final double[] lineY = new double[nbColumns];
this.extractLine(xs, ys, lineX, lineY, 0);
this.fillPts(lineX, lineY);
this.putLine(xs, ys, lineX, lineY, 0);
this.extractLine(xs, ys, lineX, lineY, lastLineIdx);
this.fillPts(lineX, lineY);
this.putLine(xs, ys, lineX, lineY, lastLineIdx);
for (int i = 0; i < nbColumns; i++) {
this.fillPts(xs[i], ys[i]);
}
}
private void extractLine(double[][] xs, double[][] ys, double[] lineX, double[] lineY, int lineIdx) {
for (int i = 0; i < xs.length; i++) {
lineX[i] = xs[i][lineIdx];
lineY[i] = ys[i][lineIdx];
}
}
private void putLine(double[][] xs, double[][] ys, double[] lineX, double[] lineY, int lineIdx) {
for (int i = 0; i < xs.length; i++) {
xs[i][lineIdx] = lineX[i];
ys[i][lineIdx] = lineY[i];
}
}
private void fillPts(double[] xs, double ys[]) {
final int divider = xs.length - 1;
final double deltaX = Math.abs(xs[0] - xs[divider]) / divider;
final double deltaY = Math.abs(ys[0] - ys[divider]) / divider;
final int factorX = (xs[0] < xs[divider]) ? 1 : -1;
final int factorY = (ys[0] < ys[divider]) ? 1 : -1;
for (int i = 1; i < divider; i++) {
xs[i] = xs[0] + (i * factorX * deltaX);
ys[i] = ys[0] + (i * factorY * deltaY);
}
}
private int[][] convertPtsToNodesIndex(double[][] xs, double[][] ys, List nodes, Map nodesIdx) {
final int length1 = xs.length;
final int length2 = xs[0].length;
final int[][] idxs = new int[length1][length2];
for (int i = 0; i < length1; i++) {
for (int j = 0; j < length2; j++) {
final EfNode node = new EfNode(xs[i][j], ys[i][j], 0.0);
Integer idx = nodesIdx.get(node);
if (idx == null) {
idx = nodes.size();
nodesIdx.put(node, idx);
nodes.add(node);
}
idxs[i][j] = idx;
}
}
return idxs;
}
private void createElements(int[][] nodes, List elements) {
final int length1 = nodes.length;
final int length2 = nodes[0].length;
for (int i = 0; i < length1 - 1; i++) {
for (int j = 0; j < length2 - 1; j++) {
// Triangle
TIntArrayList idxList = new TIntArrayList();
idxList.add(nodes[i][j]);
addIfNotPresent(idxList, nodes[i][j + 1]);
addIfNotPresent(idxList, nodes[i + 1][j + 1]);
addIfNotPresent(idxList, nodes[i + 1][j]);
EfElement element = new EfElement(idxList.toNativeArray());
elements.add(element);
}
}
}
private void addIfNotPresent(TIntArrayList idxList, int idx) {
if (!idxList.contains(idx)) {
idxList.add(idx);
}
}
}