/*
* Copyright 2014 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.polyworld.graph;
import org.terasology.math.geom.BaseVector2f;
import org.terasology.math.geom.Vector2f;
import org.terasology.math.geom.Vector3f;
import com.google.common.base.Preconditions;
/**
* Defines a triangle in the region-based {@link Graph} structure.
*/
public class Triangle {
private final Region region;
private final Corner c1;
private final Corner c2;
/**
* @param region
* @param c1
* @param c2
*/
public Triangle(Region region, Corner c1, Corner c2) {
Preconditions.checkArgument(region != null);
Preconditions.checkArgument(c1 != null);
Preconditions.checkArgument(c2 != null);
Preconditions.checkArgument(!c1.equals(c2), "c1 must be different from c2");
this.region = region;
this.c1 = c1;
this.c2 = c2;
}
public Region getRegion() {
return region;
}
public Corner getCorner1() {
return c1;
}
public Corner getCorner2() {
return c2;
}
public float computeInterpolated(Vector2f p, float wreg, float wc1, float wc2) {
Vector3f bary = computeBarycentricCoordinates(p);
return wreg * bary.getX() + wc1 * bary.getY() + wc2 * bary.getZ();
}
public Vector3f computeBarycentricCoordinates(Vector2f p) {
return computeBarycentricCoordinates(region.getCenter(), c1.getLocation(), c2.getLocation(), p);
}
public static boolean barycoordInsideTriangle(Vector3f bary) {
return bary.getX() >= 0 && bary.getY() >= 0 && bary.getX() + bary.getY() <= 1;
}
private static Vector3f computeBarycentricCoordinates(BaseVector2f a, BaseVector2f b, BaseVector2f c, BaseVector2f p) {
Vector2f v0 = new Vector2f(b).sub(a);
Vector2f v1 = new Vector2f(c).sub(a);
Vector2f v2 = new Vector2f(p).sub(a);
float d00 = v0.dot(v0);
float d01 = v0.dot(v1);
float d11 = v1.dot(v1);
float d20 = v2.dot(v0);
float d21 = v2.dot(v1);
float denom = d00 * d11 - d01 * d01;
float u = (d11 * d20 - d01 * d21) / denom;
float v = (d00 * d21 - d01 * d20) / denom;
float w = 1.0f - u - v;
// note that w is the first parameter
return new Vector3f(w, u, v);
}
@Override
public String toString() {
return String.format("Triangle [region=%s, c1=%s, c2=%s]", region, c1, c2);
}
}