126 lines
4.0 KiB
C#
126 lines
4.0 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
public static class AdvancedMath {
|
|
|
|
public static float TriangleSquare(Vector3 va, Vector3 vb, Vector3 vc){
|
|
float a = Vector3.Distance (va, vb);
|
|
float b = Vector3.Distance (vb, vc);
|
|
float c = Vector3.Distance (vc, va);
|
|
float p = (a + b + c) * 0.5f;
|
|
return Mathf.Sqrt (p * (p - a) * (p - b) * (p - c));
|
|
}
|
|
|
|
|
|
|
|
public static Vector3 PrismCenterOfMass(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 normal, float h0, float h1, float h2){
|
|
|
|
|
|
Vector3 a = v0 + normal * (h0 * 0.5f);
|
|
Vector3 c = v1 + normal * (h1 * 0.5f);
|
|
Vector3 b = v2 + normal * (h2 * 0.5f);
|
|
|
|
Vector3 f = (a + b + c) / 3.0f;
|
|
|
|
return (h0 * ((3.0f * f + a) / 4.0f) + h1 * ((3.0f * f + c) / 4.0f) + h2 * ((3.0f * f + b) / 4.0f)) / (h0 + h1 + h2);
|
|
}
|
|
|
|
public static float CylinderVolume(float r, float h){
|
|
return Mathf.PI * (r * r) * h;
|
|
}
|
|
|
|
public static Vector3 TriangleNormal(Vector3 va, Vector3 vb, Vector3 vc){
|
|
Vector3 ba = vb - va;
|
|
Vector3 ca = vc - va;
|
|
return Vector3.Cross(ba, ca).normalized;
|
|
}
|
|
|
|
public static Vector3 LineNearestPoint(Vector3 a, Vector3 b, Vector3 p){
|
|
Vector3 n = (b - a).normalized;
|
|
Vector3 pa = p - a;
|
|
float d = Vector3.Dot (n, pa);
|
|
return a + n * d;
|
|
}
|
|
|
|
public static float LineDistance(Vector3 a, Vector3 b, Vector3 p){
|
|
Vector3 lp = LineNearestPoint(a, b, p);
|
|
return Vector3.Distance (lp, p);
|
|
}
|
|
|
|
public static float Drag(float envDensity, float objVelocity, float dragCoeff, float referenceaArea){
|
|
return (envDensity * (objVelocity * objVelocity) * dragCoeff * referenceaArea) * 0.5f;
|
|
}
|
|
|
|
public static float SphereDrag(float envDensity, float objVelocity, float radius){
|
|
return Drag (envDensity, objVelocity, 0.47f, Mathf.PI * (radius * radius));
|
|
}
|
|
|
|
public static float BuoyantForce(float objectV, float objectDensity, float envDensity, float g){
|
|
return objectV * envDensity * g * ((3.0f * objectDensity) / (envDensity + 2.0f * objectDensity));
|
|
}
|
|
public static float SphereSegmentVolume(float r, float h){
|
|
return (Mathf.PI * (h * h) * (3.0f * r - h)) / 3.0f;
|
|
}
|
|
public static float SphereVolume(float r){
|
|
return (4.0f * Mathf.PI * (r * r * r)) / 3.0f;
|
|
}
|
|
public static float SphereSurfaceArea(float r){
|
|
return 4.0f * Mathf.PI * (r * r);
|
|
}
|
|
public static float PrismVolume(float baseArea, float h){
|
|
return baseArea * h;
|
|
}
|
|
public static float ConeVolume(float r, float h){
|
|
return (Mathf.PI * (r * r) * h) / 3.0f;
|
|
}
|
|
public static float PyramidVolume(float baseArea, float h){
|
|
return (baseArea * h) / 3.0f;
|
|
}
|
|
public static float RightTriangleArea(float a, float b){
|
|
return a * b * 0.5f;
|
|
}
|
|
public static float MeshVolume(Vector3[] srcVertices, int[] srcIndices, Matrix4x4 tf){
|
|
Vector3[] vertices = new Vector3[srcVertices.Length];
|
|
vertices[0] = tf.MultiplyPoint3x4(srcVertices[0]);
|
|
Vector3 vMin = vertices [0];
|
|
Vector3 vMax = vertices [0];
|
|
for (int i = 1; i < vertices.Length; ++i) {
|
|
vertices[i] = tf.MultiplyPoint3x4(srcVertices[i]);
|
|
vMin = Vector3.Min(vMin, vertices[i]);
|
|
vMax = Vector3.Max(vMax, vertices[i]);
|
|
}
|
|
|
|
Plane p = new Plane (Vector3.up, vMax + Vector3.up);
|
|
|
|
//split mesh by plane
|
|
List<Vector3> cuttedTriangles = AdvancedUtils.CutMesh (vertices, srcIndices, p);
|
|
|
|
float totalVolume = 0.0f;
|
|
|
|
for (int i = 0; i < cuttedTriangles.Count; i+=3) {
|
|
Vector3 v0 = cuttedTriangles[i + 0];
|
|
Vector3 v1 = cuttedTriangles[i + 1];
|
|
Vector3 v2 = cuttedTriangles[i + 2];
|
|
Vector3 normal = AdvancedMath.TriangleNormal(v0, v1, v2);
|
|
|
|
float sign = Mathf.Sign(Vector3.Dot (normal, p.normal));
|
|
|
|
float h0 = p.GetDistanceToPoint(v0);
|
|
float h1 = p.GetDistanceToPoint(v1);
|
|
float h2 = p.GetDistanceToPoint(v2);
|
|
float avgH = (h0 + h1 + h2) / 3.0f;
|
|
|
|
Vector3 vp0 = v0 - p.normal * h0;
|
|
Vector3 vp1 = v1 - p.normal * h1;
|
|
Vector3 vp2 = v2 - p.normal * h2;
|
|
|
|
float triangleSquare = AdvancedMath.TriangleSquare(vp0, vp1, vp2);
|
|
float prismVolume = AdvancedMath.PrismVolume(triangleSquare, avgH) * sign;
|
|
totalVolume += prismVolume;
|
|
}
|
|
|
|
return totalVolume;
|
|
}
|
|
}
|