/*******************************************************************************
* This is part of SketchChair, an open-source tool for designing your own furniture.
* www.sketchchair.cc
*
* Copyright (C) 2012, Diatom Studio ltd. Contact: hello@diatom.cc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
//#IF JAVA
package cc.sketchchair.sketch;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import cc.sketchchair.core.LOGGER;
import cc.sketchchair.sketch.SketchPoint;
import processing.core.PConstants;
import processing.core.PGraphics;
import toxi.geom.Vec2D;
/**
* Static non specific functions used in Sketchchair.
* @author gregsaul
*
*/
//#ENDIF JAVA
public class functions {
public static int DONT_INTERSECT = 0;
public static int COLLINEAR = 1;
public static int DO_INTERSECT = 2;
public static float x = 0;
public static float y = 0;
public static float angleOf(Vec2D v1) {
v1.normalize();
float an = (float) Math.atan2(v1.y, v1.x);
if (an > 0.0) {
an = (float) (Math.PI + (Math.PI - an));
} else {
// no negative nums
an = (float) (Math.PI - (Math.PI - Math.abs(an)));
}
return an;
}
public static float angleOfDot(Vec2D v1) {
v1.normalize();
float an = (float) Math.acos(v1.dot(new Vec2D(0, 0)));
return (float) Math.atan2(v1.y, v1.x);
}
public static float bezierPoint(float a, float b, float c, float d, float t) {
float t1 = 1.0f - t;
return a * t1 * t1 * t1 + 3 * b * t * t1 * t1 + 3 * c * t * t * t1 + d
* t * t * t;
}
/*
public static void drawAllSprings(VerletPhysics physics, PGraphics g){
g.stroke(255,0,0);
g.strokeWeight(1f);
for ( int i = 0; i < physics.springs.size(); ++i )
{
VerletSpring s = (VerletSpring) physics.springs.get( i );
g.line(s.a.x, s.a.y,s.a.z,s.b.x, s.b.y,s.b.z);
}
}
void drawAllParticles(VerletPhysics physics, PGraphics g){
g.stroke(0,0,0,100);
for ( int i = 0; i < physics.particles.size(); ++i )
{
VerletParticle p = (VerletParticle) physics.particles.get( i );
g.sphereDetail(2);
g.pushMatrix();
g.translate(p.x,p.y,p.z);
g.sphere(p.weight*2);
g.popMatrix();
}
}
/*
public static void boundAllParticles(VerletPhysics physics){
for ( int i = 0; i < physics.particles.size(); ++i )
{
VerletParticle p = (VerletParticle) physics.particles.get( i );
if(p.y > 550)
p.y -= p.y-550;
}
}
*/
public final static int color(int x, int y, int z) {
if (x > 255)
x = 255;
else if (x < 0)
x = 0;
if (y > 255)
y = 255;
else if (y < 0)
y = 0;
if (z > 255)
z = 255;
else if (z < 0)
z = 0;
return 0xff000000 | (x << 16) | (y << 8) | z;
}
public static float curvePoint(float x2, float x3, float x4, float x5,
float t) {
// TODO Auto-generated method stub
return 0;
}
public static void cylinder(float w1, float w2, float h, int sides,
PGraphics g) {
float angle;
float[] x1 = new float[sides + 1];
float[] z1 = new float[sides + 1];
float[] x2 = new float[sides + 1];
float[] z2 = new float[sides + 1];
//get the x and z position on a circle for all the sides
for (int i = 0; i < x1.length; i++) {
angle = (float) ((Math.PI * 2) / (sides) * i + 1);
x1[i] = (float) (Math.sin(angle) * w1);
z1[i] = (float) (Math.cos(angle) * w1);
}
//get the x and z position on a circle for all the sides
for (int i = 0; i < x2.length; i++) {
angle = (float) ((Math.PI * 2) / (sides) * i + 1);
x2[i] = (float) (Math.sin(angle) * w2);
z2[i] = (float) (Math.cos(angle) * w2);
}
//draw the top of the cylinder
g.beginShape(PConstants.TRIANGLE_FAN);
g.vertex(0, -h / 2, 0);
for (int i = 0; i < x1.length; i++) {
g.vertex(x1[i], -h / 2, z1[i]);
}
g.endShape();
//draw the center of the cylinder
g.beginShape(PConstants.QUAD_STRIP);
for (int i = 0; i < x1.length; i++) {
g.vertex(x1[i], -h / 2, z1[i]);
g.vertex(x2[i], h / 2, z2[i]);
}
g.endShape();
//draw the bottom of the cylinder
g.beginShape(PConstants.TRIANGLE_FAN);
g.vertex(0, h / 2, 0);
for (int i = 0; i < x2.length; i++) {
g.vertex(x2[i], h / 2, z2[i]);
}
g.endShape();
}
public static void cylinder(float w, float h, int sides, PGraphics g) {
float angle;
float[] x = new float[sides + 1];
float[] z = new float[sides + 1];
//get the x and z position on a circle for all the sides
for (int i = 0; i < x.length; i++) {
angle = (float) ((Math.PI * 2) / (sides) * i);
x[i] = (float) (Math.sin(angle) * w);
z[i] = (float) (Math.cos(angle) * w);
}
//draw the top of the cylinder
g.beginShape(PConstants.TRIANGLE_FAN);
g.vertex(0, -h / 2, 0);
for (int i = 0; i < x.length; i++) {
g.vertex(x[i], -h / 2, z[i]);
}
g.endShape();
//draw the center of the cylinder
g.beginShape(PConstants.QUAD_STRIP);
for (int i = 0; i < x.length; i++) {
g.vertex(x[i], -h / 2, z[i]);
g.vertex(x[i], h / 2, z[i]);
}
g.endShape();
//draw the bottom of the cylinder
g.beginShape(PConstants.TRIANGLE_FAN);
g.vertex(0, h / 2, 0);
for (int i = 0; i < x.length; i++) {
g.vertex(x[i], h / 2, z[i]);
}
g.endShape();
}
public static boolean fileExists(String filename) {
File file = new File(filename);
if (!file.exists())
return false;
return true;
}
public static String getComputerName() {
return "name";
/*
try{
String computername=InetAddress.getLocalHost().getHostName();
return computername;
}catch (Exception e){
return null;
}\*/
}
public static String getFileName() {
Calendar now = Calendar.getInstance();
Long time = now.getTimeInMillis();
return time.toString();
}
public static ByteBuffer getIndexBuffer(int[] indices) {
ByteBuffer buf = ByteBuffer.allocateDirect(indices.length * 4).order(
ByteOrder.nativeOrder());
for (int i = 0; i < indices.length; i++) {
buf.putInt(indices[i]);
}
buf.flip();
return buf;
}
public static ByteBuffer getVertexBuffer(float[] vertices) {
ByteBuffer buf = ByteBuffer.allocateDirect(vertices.length * 4).order(
ByteOrder.nativeOrder());
for (int i = 0; i < vertices.length; i++) {
buf.putFloat(vertices[i]);
}
buf.flip();
return buf;
}
public static int intersect(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4) {
float a1, a2, b1, b2, c1, c2;
float r1, r2, r3, r4;
float denom, offset, num;
// Compute a1, b1, c1, where line joining points 1 and 2
// is "a1 x + b1 y + c1 = 0".
a1 = y2 - y1;
b1 = x1 - x2;
c1 = (x2 * y1) - (x1 * y2);
// Compute r3 and r4.
r3 = ((a1 * x3) + (b1 * y3) + c1);
r4 = ((a1 * x4) + (b1 * y4) + c1);
// Check signs of r3 and r4. If both point 3 and point 4 lie on
// same side of line 1, the line segments do not intersect.
if ((r3 != 0) && (r4 != 0) && same_sign(r3, r4)) {
return DONT_INTERSECT;
}
// Compute a2, b2, c2
a2 = y4 - y3;
b2 = x3 - x4;
c2 = (x4 * y3) - (x3 * y4);
// Compute r1 and r2
r1 = (a2 * x1) + (b2 * y1) + c2;
r2 = (a2 * x2) + (b2 * y2) + c2;
// Check signs of r1 and r2. If both point 1 and point 2 lie
// on same side of second line segment, the line segments do
// not intersect.
if ((r1 != 0) && (r2 != 0) && (same_sign(r1, r2))) {
return DONT_INTERSECT;
}
//Line segments intersect: compute intersection point.
denom = (a1 * b2) - (a2 * b1);
if (denom == 0) {
return COLLINEAR;
}
if (denom < 0) {
offset = -denom / 2;
} else {
offset = denom / 2;
}
// The denom/2 is to get rounding instead of truncating. It
// is added or subtracted to the numerator, depending upon the
// sign of the numerator.
num = (b1 * c2) - (b2 * c1);
if (num < 0) {
x = (num - offset) / denom;
} else {
x = (num + offset) / denom;
}
num = (a2 * c1) - (a1 * c2);
if (num < 0) {
y = (num - offset) / denom;
} else {
y = (num + offset) / denom;
}
// lines_intersect
return DO_INTERSECT;
}
public static int intersect(Vec2D a1, Vec2D a2, Vec2D b1, Vec2D b2,
Vec2D b3, Vec2D b4) {
if (functions.intersect(a1.x, a1.y, a2.x, a2.y, b1.x, b1.y, b2.x, b2.y) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a1.x, a1.y, a2.x, a2.y, b2.x, b2.y, b3.x, b3.y) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a1.x, a1.y, a2.x, a2.y, b3.x, b3.y, b4.x, b4.y) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a1.x, a1.y, a2.x, a2.y, b4.x, b4.y, b1.x, b1.y) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
return functions.DONT_INTERSECT;
}
public static int intersect(Vec2D a1, Vec2D a2, Vec2D a3, Vec2D a4,
Vec2D b1, Vec2D b2, Vec2D b3, Vec2D b4) {
if (functions.intersect(a1, a2, b1, b2, b3, b4) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a2, a3, b1, b2, b3, b4) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a3, a4, b1, b2, b3, b4) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
if (functions.intersect(a4, a1, b1, b2, b3, b4) == functions.DO_INTERSECT)
return functions.DO_INTERSECT;
return functions.DONT_INTERSECT;
}
static boolean same_sign(float a, float b) {
return ((a * b) >= 0);
}
public final int color(float x, float y, float z) {
if (x > 255)
x = 255;
else if (x < 0)
x = 0;
if (y > 255)
y = 255;
else if (y < 0)
y = 0;
if (z > 255)
z = 255;
else if (z < 0)
z = 0;
return 0xff000000 | ((int) x << 16) | ((int) y << 8) | (int) z;
}
/**
* Creates colors for storing in variables of the <b>color</b> datatype. The parameters are interpreted as RGB or HSB values depending on the current <b>colorMode()</b>. The default mode is RGB values from 0 to 255 and therefore, the function call <b>color(255, 204, 0)</b> will return a bright yellow color. More about how colors are stored can be found in the reference for the <a href="color_datatype.html">color</a> datatype.
*
* @webref color:creating_reading
* @param x red or hue values relative to the current color range
* @param y green or saturation values relative to the current color range
* @param z blue or brightness values relative to the current color range
* @param a alpha relative to current color range
*
* @see processing.core.PApplet#colorMode(int)
* @ref color_datatype
*/
public final int color(float x, float y, float z, float a) {
if (a > 255)
a = 255;
else if (a < 0)
a = 0;
if (x > 255)
x = 255;
else if (x < 0)
x = 0;
if (y > 255)
y = 255;
else if (y < 0)
y = 0;
if (z > 255)
z = 255;
else if (z < 0)
z = 0;
return ((int) a << 24) | ((int) x << 16) | ((int) y << 8) | (int) z;
}
public final static int color(int x, int y, int z, int a) {
if (a > 255)
a = 255;
else if (a < 0)
a = 0;
if (x > 255)
x = 255;
else if (x < 0)
x = 0;
if (y > 255)
y = 255;
else if (y < 0)
y = 0;
if (z > 255)
z = 255;
else if (z < 0)
z = 0;
return (a << 24) | (x << 16) | (y << 8) | z;
}
public static Vec2D rotate(Vec2D curVec, Vec2D center, float r) {
Vec2D returnVec = curVec.copy();
returnVec.subSelf(center);
returnVec.rotate(r);
returnVec.addSelf(center);
return returnVec;
}
public static List getRange(List l, int start,
int end) {
List returnList = new ArrayList();
for(int i = start; i <= end; i++)
returnList.add(l.get(i));
return returnList;
}
}