public TranslateField(double x0, double y0, double z0, IScalarField field) { this.x0 = x0; this.y0 = y0; this.z0 = z0; this.field = field; }
public ScaleField(double sx, double sy, double sz, IScalarField field) { this.sx = sx; this.sy = sy; this.sz = sz; this.field = field; }
public void Render(IScalarField field, Vector3 size, Matrix4x4 transformation) { if (!ShowField || _fieldSamplingRate < MinSamplingRate) { return; } var step = 1 / _fieldSamplingRate; var transform = Camera.current.transform; var right = transform.right * step; var up = transform.up * step; var lt = up - right; var rt = up + right; var rb = -up + right; var lb = -up - right; Material.Value.SetPass(0); GL.PushMatrix(); GL.MultMatrix(transformation); GL.Begin(GL.QUADS); GL.Color(Color.black); for (float x = 0; x < size.x; x += step) { for (float y = 0; y < size.y; y += step) { for (float z = 0; z < size.z; z += step) { var position = new Vector3(x, y, z); var rawValue = field.GetValue(position); var scaledValue = Mathf.InverseLerp(_minValue, _maxValue, rawValue); if (scaledValue > 0 && scaledValue < 1) { var value = Mathf.Clamp01(scaledValue); var scale = Mathf.Lerp(_minSize, _maxSize, value); var color = _gradient.Evaluate(scale); GL.Color(color); GL.Vertex(position + lt); GL.Vertex(position + rt); GL.Vertex(position + rb); GL.Vertex(position + lb); } } } } GL.End(); GL.PopMatrix(); }
/// <summary> /// Traverses a path of steepest ascent/descent until the desired potential is reached. /// </summary> /// <param name="pos">Starting point</param> /// <param name="desiredPotential">The field value you want to reach</param> /// <returns>The position the traversal ends at</returns> public static Vector3 GradientTraversal(this IScalarField field, Vector3 pos, double desiredPotential, double tolerance) { const double stepSize = 0.5; // TODO: tune this Vector3 currentPos = pos; double potentialDiff = desiredPotential - field.Value(currentPos); while (Math.Abs(potentialDiff) >= tolerance) { currentPos = currentPos + (stepSize * potentialDiff) * field.Gradient(pos); potentialDiff = desiredPotential - field.Value(currentPos); } return(pos); }
public void Init(IScalarField field) { Voxels = new Voxel[Width][][]; for (int i = 0; i < Width; i++) { Voxels[i] = new Voxel[Height][]; for (int j = 0; j < Height; j++) { Voxels[i][j] = new Voxel[Depth]; } } Dx = (XMax - XMin) / Width; Dy = (YMax - YMin) / Height; Dz = (ZMax - ZMin) / Depth; InitVoxels(field); }
private void InitVoxels(IScalarField field) { for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { for (int k = 0; k < Depth; k++) { double x = XMin + i * Dx; double y = YMin + j * Dy; double z = ZMin + k * Dz; var value = field.F(x, y, z); Voxels[i][j][k] = new Voxel { X = x, Y = y, Z = z, Value = value }; } } } }
public override void OnToolGUI(IScalarField field) => OnToolGUI((T)field);
/// <summary> /// Adds this scalar field to another. /// </summary> public static SumScalarField Add(this IScalarField f, IScalarField other) => new SumScalarField(f, other);
public TranslatedScalarField(IScalarField underlyingScalarField, Generator<Vector3> translationGen) { UnderlyingScalarField = underlyingScalarField; this.translationGen = translationGen; }
/// <summary> /// Returns a new scalar field with the origin moved by a specified translation generator. /// </summary> public static TranslatedScalarField Translate(this IScalarField f, Generator <Vector3> translation) => new TranslatedScalarField(f, translation);
/// <summary> /// Returns a new scalar field that is 'clamped' outside a specified volume of influence. /// When clamped the value of the field is zero. /// </summary> public static ClampedScalarField Clamp(this IScalarField f, Func <Vector3, bool> clampFunction) => new ClampedScalarField(f, clampFunction);
public ScalarFieldManifold(IScalarField s, double potential) { UnderlyingScalarField = s; PotentialValue = potential; }
/// <summary> /// Multiplies this scalar field by a constant value. /// </summary> public static ProductScalarField Multiply(this IScalarField f, double mult) => new ProductScalarField(f, mult);
public SumScalarField(IScalarField a, IScalarField b) { A = a; B = b; }
public ConstantDirectionVectorField(IScalarField scalarComp, Vector3 vectorComp) { ScalarComponent = scalarComp; ConstantVectorComponent = vectorComp; }
public SphericalVectorField(IScalarField r, IScalarField theta, IScalarField phi) { R = r; Theta = theta; Phi = phi; }
public ProductScalarField(IScalarField origField, Generator <double> multiplierGen) { this.multiplierGen = multiplierGen; UnderlyingScalarField = origField; }
public ProductScalarField(IScalarField origField, double constantMultiplier) : this(origField, () => constantMultiplier) { }
public ClampedScalarField(IScalarField origScalarField, Func <Vector3, bool> clampFunction) { UnderlyingScalarField = origScalarField; ClampFunction = clampFunction; }
public InvSqrField(IScalarField field) { Field = field; }
public void Polygonize(IScalarField field, float isoLevel, Size3 step, Size3Int size, IMeshBuilder builder, CancellationToken cancellationToken) { var positions = new Vector3[8]; var values = new float[8]; // Cache values along z axis var prevRowX0 = new float[size.Z + 1]; var prevRowX1 = new float[size.Z + 1]; for (var i = 0; i < size.X; i++) { for (var k = 0; k < size.Z + 1; k++) { prevRowX0[k] = field.GetValue(new Vector3((i + 0) * step.X, (0 + 0) * step.Y, (k + 0) * step.Z)); prevRowX1[k] = field.GetValue(new Vector3((i + 1) * step.X, (0 + 0) * step.Y, (k + 0) * step.Z)); } for (var j = 0; j < size.Y; j++) { // Initial values, will go into 0, 3, 4, 7 at k == 0 positions[1] = new Vector3((i + 0) * step.X, (j + 0) * step.Y, (0 + 0) * step.Z); positions[2] = new Vector3((i + 1) * step.X, (j + 0) * step.Y, (0 + 0) * step.Z); positions[5] = new Vector3((i + 0) * step.X, (j + 1) * step.Y, (0 + 0) * step.Z); positions[6] = new Vector3((i + 1) * step.X, (j + 1) * step.Y, (0 + 0) * step.Z); values[1] = prevRowX0[0]; values[2] = prevRowX1[0]; values[5] = prevRowX0[0] = field.GetValue(positions[5]); values[6] = prevRowX1[0] = field.GetValue(positions[6]); for (var k = 0; k < size.Z; k++) { if (cancellationToken.IsCancellationRequested) { return; } positions[0] = positions[1]; positions[3] = positions[2]; positions[4] = positions[5]; positions[7] = positions[6]; positions[1] = new Vector3(positions[1].x, positions[1].y, positions[1].z + step.Z); positions[2] = new Vector3(positions[2].x, positions[2].y, positions[2].z + step.Z); positions[5] = new Vector3(positions[5].x, positions[5].y, positions[5].z + step.Z); positions[6] = new Vector3(positions[6].x, positions[6].y, positions[6].z + step.Z); Profiler.BeginSample("GetValue"); values[0] = values[1]; values[3] = values[2]; values[4] = values[5]; values[7] = values[6]; values[1] = prevRowX0[k + 1]; values[2] = prevRowX1[k + 1]; values[5] = prevRowX0[k + 1] = field.GetValue(positions[5]); values[6] = prevRowX1[k + 1] = field.GetValue(positions[6]); Profiler.EndSample(); PolygonizeCell(values, positions, isoLevel, builder); } } } }
public static IScalarField Translate(this IScalarField field, double x, double y, double z) => new TranslateField(x, y, z, field);
public TranslatedScalarField(IScalarField underlyingScalarField, Generator <Vector3> translationGen) { UnderlyingScalarField = underlyingScalarField; this.translationGen = translationGen; }
public static ConstantDirectionVectorField Multiply(this IScalarField sf, Vector3 vectorComp) => new ConstantDirectionVectorField(sf, vectorComp);
public ClampedScalarField(IScalarField origScalarField, Func<Vector3, bool> clampFunction) { UnderlyingScalarField = origScalarField; ClampFunction = clampFunction; }
public static IScalarField InvSqr(this IScalarField field) => new InvSqrField(field);
public static IScalarField Scale(this IScalarField field, double x, double y, double z) => new ScaleField(x, y, z, field);
/// <summary> /// Returns a new scalar field with the origin moved to a specified position. /// </summary> public static TranslatedScalarField Translate(this IScalarField f, Vector3 translation) => new TranslatedScalarField(f, () => translation);
public ProductScalarField(IScalarField origField, Generator<double> multiplierGen) { this.multiplierGen = multiplierGen; UnderlyingScalarField = origField; }
/// <summary> /// Generates a manifold from this scalar field at a certain potential. /// This is an equipotential surface of this scalar field. /// </summary> public static ScalarFieldManifold ToManifold(this IScalarField field, double potential) => new ScalarFieldManifold(field, potential);