/******************************************************************************* * Copyright 2011 See AUTHORS file. * * 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 com.badlogic.gdx.math; public class Polyline implements Shape2D { private float[] localVertices; private float[] worldVertices; private float x, y; private float originX, originY; private float rotation; private float scaleX = 1, scaleY = 1; private float length; private float scaledLength; private boolean calculateScaledLength = true; private boolean calculateLength = true; private boolean dirty = true; public Polyline () { this.localVertices = new float[0]; } public Polyline (float[] vertices) { if (vertices.length < 4) throw new IllegalArgumentException("polylines must contain at least 2 points."); this.localVertices = vertices; } /** Returns vertices without scaling or rotation and without being offset by the polyline position. */ public float[] getVertices () { return localVertices; } /** Returns vertices scaled, rotated, and offset by the polygon position. */ public float[] getTransformedVertices () { if (!dirty) return worldVertices; dirty = false; final float[] localVertices = this.localVertices; if (worldVertices == null || worldVertices.length < localVertices.length) worldVertices = new float[localVertices.length]; final float[] worldVertices = this.worldVertices; final float positionX = x; final float positionY = y; final float originX = this.originX; final float originY = this.originY; final float scaleX = this.scaleX; final float scaleY = this.scaleY; final boolean scale = scaleX != 1 || scaleY != 1; final float rotation = this.rotation; final float cos = MathUtils.cosDeg(rotation); final float sin = MathUtils.sinDeg(rotation); for (int i = 0, n = localVertices.length; i < n; i += 2) { float x = localVertices[i] - originX; float y = localVertices[i + 1] - originY; // scale if needed if (scale) { x *= scaleX; y *= scaleY; } // rotate if needed if (rotation != 0) { float oldX = x; x = cos * x - sin * y; y = sin * oldX + cos * y; } worldVertices[i] = positionX + x + originX; worldVertices[i + 1] = positionY + y + originY; } return worldVertices; } /** Returns the euclidean length of the polyline without scaling */ public float getLength () { if (!calculateLength) return length; calculateLength = false; length = 0; for (int i = 0, n = localVertices.length - 2; i < n; i += 2) { float x = localVertices[i + 2] - localVertices[i]; float y = localVertices[i + 1] - localVertices[i + 3]; length += (float)Math.sqrt(x * x + y * y); } return length; } /** Returns the euclidean length of the polyline */ public float getScaledLength () { if (!calculateScaledLength) return scaledLength; calculateScaledLength = false; scaledLength = 0; for (int i = 0, n = localVertices.length - 2; i < n; i += 2) { float x = localVertices[i + 2] * scaleX - localVertices[i] * scaleX; float y = localVertices[i + 1] * scaleY - localVertices[i + 3] * scaleY; scaledLength += (float)Math.sqrt(x * x + y * y); } return scaledLength; } public float getX () { return x; } public float getY () { return y; } public float getOriginX () { return originX; } public float getOriginY () { return originY; } public float getRotation () { return rotation; } public float getScaleX () { return scaleX; } public float getScaleY () { return scaleY; } public void setOrigin (float originX, float originY) { this.originX = originX; this.originY = originY; dirty = true; } public void setPosition (float x, float y) { this.x = x; this.y = y; dirty = true; } public void setVertices (float[] vertices) { if (vertices.length < 4) throw new IllegalArgumentException("polylines must contain at least 2 points."); this.localVertices = vertices; dirty = true; } public void setRotation (float degrees) { this.rotation = degrees; dirty = true; } public void rotate (float degrees) { rotation += degrees; dirty = true; } public void setScale (float scaleX, float scaleY) { this.scaleX = scaleX; this.scaleY = scaleY; dirty = true; calculateScaledLength = true; } public void scale (float amount) { this.scaleX += amount; this.scaleY += amount; dirty = true; calculateScaledLength = true; } public void calculateLength () { calculateLength = true; } public void calculateScaledLength () { calculateScaledLength = true; } public void dirty () { dirty = true; } public void translate (float x, float y) { this.x += x; this.y += y; dirty = true; } @Override public boolean contains (Vector2 point) { return false; } @Override public boolean contains (float x, float y) { return false; } }