/// <summary>
        /// Interpolate source values to target
        /// </summary>
        public void Interpolate(double[] sourceValues, double[] targetValues)
        {
            // Loop over all target elements/nodes
            for (int i = 0; i < _interpData.Length; i++)
            {
                InterPData interPData = _interpData[i];

                double value  = 0;
                double weight = 0;

                int[]    indices = interPData.Indices;
                double[] weights = interPData.Weights;

                // For angular-type data, find reference value
                double refValue = 0;
                if (_circularType != CircularValueTypes.Normal)
                {
                    for (int j = 0; j < indices.Length; j++)
                    {
                        double sourceValue = sourceValues[indices[j]];
                        if (sourceValue != _deleteValue)
                        {
                            // First one found is good, break out.
                            refValue = sourceValue;
                            break;
                        }
                    }
                }

                // Loop over all source elements connected to target
                for (int j = 0; j < indices.Length; j++)
                {
                    double sourceValue = sourceValues[indices[j]];

                    if (sourceValue != _deleteValue)
                    {
                        // For angular type values, correct to match reference value
                        CircularValueHandler.ToReference(_circularType, ref sourceValue, refValue);

                        value  += sourceValue * weights[j];
                        weight += weights[j];
                    }
                }

                if (weight == 0) // all element values were delete values
                {
                    targetValues[i] = _deleteValue;
                }
                else
                {
                    value /= weight;

                    // For angular type values, correct to match angular span.
                    CircularValueHandler.ToCircular(_circularType, ref value);

                    targetValues[i] = value;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Interpolate values from source (element values) to target points.
        /// </summary>
        public void InterpolateToTarget(double[] sourceElementValues, double[] target)
        {
            // Firstly, interpolate to node values
            _nodeInterpolator.Interpolate(sourceElementValues, _nodeValues);

            for (int i = 0; i < _targets.Count; i++)
            {
                InterPData interPData = _targets[i];
                if (interPData.Element1Index < 0)
                {
                    // target not included in source
                    target[i] = _deleteValue;
                    continue;
                }

                // Do interpolation inside (element-element-node) triangle,
                // disregarding any delete values.
                double sourceElementValue = sourceElementValues[interPData.Element1Index];
                if (sourceElementValue != _deleteValue)
                {
                    double value  = sourceElementValue * interPData.Element1Weight;
                    double weight = interPData.Element1Weight;

                    {
                        double otherElmentValue = sourceElementValues[interPData.Element2Index];
                        if (otherElmentValue != _deleteValue)
                        {
                            CircularValueHandler.ToReference(_circularType, ref otherElmentValue, sourceElementValue);
                            value  += otherElmentValue * interPData.Element2Weight;
                            weight += interPData.Element2Weight;
                        }
                    }

                    {
                        double nodeValue = _nodeValues[interPData.NodeIndex];
                        if (nodeValue != _deleteValue)
                        {
                            CircularValueHandler.ToReference(_circularType, ref nodeValue, sourceElementValue);
                            value  += nodeValue * interPData.NodeWeight;
                            weight += interPData.NodeWeight;
                        }
                    }

                    value /= weight;
                    CircularValueHandler.ToCircular(_circularType, ref value);
                    target[i] = value;
                }
                else
                {
                    target[i] = _deleteValue;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Returns interpolated value based on 3 node values
        /// <para>
        /// In case values are one of the circular types in <see cref="CircularValueTypes"/>,
        /// then the values must first be re-referenced, <see cref="CircularValueHandler"/>.
        /// </para>
        /// </summary>
        /// <param name="T1">Node value 1</param>
        /// <param name="T2">Node value 2</param>
        /// <param name="T3">Node value 3</param>
        /// <param name="w1">Weights for node value 1</param>
        /// <param name="w2">Weights for node value 2</param>
        /// <param name="w3">Weights for node value 3</param>
        /// <returns>Interpolated value</returns>
        public double GetValue(
            double w1,
            double w2,
            double w3,
            double T1,
            double T2,
            double T3
            )
        {
            if (CircularType != CircularValueTypes.Normal)
            {
                double circReference = DelVal;
                // Try find circReference value - the first non-delete value
                if (CircularValueHandler.AsReference(T1, ref circReference, DelVal) ||
                    CircularValueHandler.AsReference(T2, ref circReference, DelVal) ||
                    CircularValueHandler.AsReference(T3, ref circReference, DelVal))
                {
                    CircularValueHandler.ToReference(CircularType, ref T1, circReference, DelVal);
                    CircularValueHandler.ToReference(CircularType, ref T2, circReference, DelVal);
                    CircularValueHandler.ToReference(CircularType, ref T3, circReference, DelVal);
                }
            }

            double value      = 0;
            double weight     = 0;
            int    delValMask = 0;

            // Delete value mask values for each node
            const int dvm1 = 0x1;
            const int dvm2 = 0x2;
            const int dvm3 = 0x4;

            if (T1 != DelVal)
            {
                value  += w1 * T1;
                weight += w1;
            }
            // T1 is delete value - If we are close to this node, return delVal
            else if (w1 > 0.5)
            {
                return(DelVal);
            }
            else
            {
                delValMask |= dvm1;
            }

            if (T2 != DelVal)
            {
                value  += w2 * T2;
                weight += w2;
            }
            // T2 is delete value - If we are close to this node, return delVal
            else if (w2 > 0.5)
            {
                return(DelVal);
            }
            else
            {
                delValMask |= dvm2;
            }

            if (T3 != DelVal)
            {
                value  += w3 * T3;
                weight += w3;
            }
            // T3 is delete value - If we are close to this node, return delVal
            else if (w3 > 0.5)
            {
                return(DelVal);
            }
            else
            {
                delValMask |= dvm3;
            }

            // Check if only one non-delete value is present
            switch (delValMask)
            {
            //case 0: // All had values
            //  return value;

            case dvm1: // Only one delete value, and we are outside the
            case dvm2: // "delete value area".
            case dvm3: // Weight them accordingly
                value = value / weight;
                break;

            case dvm1 + dvm2: // Only T3 is non-delete
                // If we are close to T3, use that, otherwise delVal
                value = (w3 > 0.5) ? T3 : DelVal;
                break;

            case dvm2 + dvm3: // Only T1 is non-delete
                // If we are close to T1, use that, otherwise delVal
                value = (w1 > 0.5) ? T1 : DelVal;
                break;

            case dvm3 + dvm1: // Only T2 is non-delete
                // If we are close to T2, use that, otherwise delVal
                value = (w2 > 0.5) ? T2 : DelVal;
                break;
            }

            CircularValueHandler.ToCircular(CircularType, ref value);
            return(value);
        }
예제 #4
0
        /// <summary>
        /// Returns interpolated value based on 4 node values
        /// <para>
        /// In case values are one of the circular types in <see cref="CircularValueTypes"/>,
        /// then the values must first be re-referenced, <see cref="CircularValueHandler"/>.
        /// </para>
        /// </summary>
        /// <param name="dx">Bilinear dx interpolation weights</param>
        /// <param name="dy">Bilinear dy interpolation weights</param>
        /// <param name="T00">Node value 1</param>
        /// <param name="T10">Node value 2</param>
        /// <param name="T11">Node value 3</param>
        /// <param name="T01">Node value 4</param>
        /// <returns>Interpolated value</returns>
        // Matching CMzQuadrangle::GetValue
        public double GetValue(
            double dx,
            double dy,
            double T00,
            double T10,
            double T11,
            double T01
            )
        {
            if (CircularType != CircularValueTypes.Normal)
            {
                double circReference = DelVal;
                // Try find circReference value - the first non-delete value
                if (CircularValueHandler.AsReference(T00, ref circReference, DelVal) ||
                    CircularValueHandler.AsReference(T01, ref circReference, DelVal) ||
                    CircularValueHandler.AsReference(T11, ref circReference, DelVal) ||
                    CircularValueHandler.AsReference(T10, ref circReference, DelVal))
                {
                    CircularValueHandler.ToReference(CircularType, ref T00, circReference, DelVal);
                    CircularValueHandler.ToReference(CircularType, ref T01, circReference, DelVal);
                    CircularValueHandler.ToReference(CircularType, ref T11, circReference, DelVal);
                    CircularValueHandler.ToReference(CircularType, ref T10, circReference, DelVal);
                }
            }

            int deleteValueMask = DeleteValueMask(T00, T10, T11, T01);

            const double m_xc = 0.5;
            const double m_yc = 0.5;


            double z;

            switch (deleteValueMask)
            {
            case 0: // Default
                if ((T00 == T10) && (T00 == T01) && (T00 == T11))
                {
                    z = T00;
                }
                else
                {
                    z = (1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 +
                        (1 - dx) * dy * T01 + dx * dy * T11;
                }
                break;

            case 1: // Delete value: T00
                if ((dx < m_xc) && (dy < m_yc))
                {
                    z = DelVal;
                }
                else
                {
                    z = (dx * (1 - dy) * T10 + (1 - dx) * dy * T01 + dx * dy * T11) /
                        (dx + dy - dx * dy);
                }
                break;

            case 2: // Delete value: T10
                if ((dx >= m_xc) && (dy < m_yc))
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + (1 - dx) * dy * T01 + dx * dy * T11) /
                        (1 - dx + dx * dy);
                }
                break;

            case 3: // Delete value: T00+T10
                if (dy < m_yc)
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * T01 + dx * T11);
                }
                break;

            case 4: // Delete value: T01
                if ((dx < m_xc) && (dy >= m_yc))
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 + dx * dy * T11) /
                        (1 - dy + dx * dy);
                }
                break;

            case 5: // Delete value: T00+T01
                if (dx < m_xc)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dy) * T10 + dy * T11;
                }
                break;

            case 6: // Delete value: T10+T01
                if (((dx < m_xc) && (dy >= m_yc)) || ((dx >= m_xc) && (dy < m_yc)))
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * dy * T11) /
                        (1 - dx - dy + 2 * dx * dy);
                }
                break;

            case 7: // Delete value: T00+T10+T01
                if ((dx >= m_xc) && (dy >= m_yc))
                {
                    z = T11;
                }
                else
                {
                    z = DelVal;
                }
                break;

            case 8: // Delete value: T11
                if ((dx >= m_xc) && (dy >= m_yc))
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 +
                         (1 - dx) * dy * T01) /
                        (1 - dx * dy);
                }
                break;

            case 9: // Delete value: T00+T11
                if (((dx < m_xc) && (dy < m_yc)) || ((dx >= m_xc) && (dy >= m_yc)))
                {
                    z = DelVal;
                }
                else
                {
                    z = (dx * (1 - dy) * T10 + (1 - dx) * dy * T01) /
                        (dx + dy - 2 * dx * dy);
                }
                break;

            case 10: // Delete value: T10+T11
                if (dx >= m_xc)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dy) * T00 + dy * T01;
                }
                break;

            case 11: // Delete value: T00+T10+T11
                if ((dx < m_xc) && (dy >= m_yc))
                {
                    z = T01;
                }
                else
                {
                    z = DelVal;
                }
                break;

            case 12: // Delete value: T01+T11
                if (dy >= m_yc)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dx) * T00 + dx * T10;
                }
                break;

            case 13: // Delete value: T00+T01+T11
                if ((dx >= m_xc) && (dy < m_yc))
                {
                    z = T10;
                }
                else
                {
                    z = DelVal;
                }
                break;

            case 14: // Delete value: T10+T01+T11
                if ((dx < m_xc) && (dy < m_yc))
                {
                    z = T00;
                }
                else
                {
                    z = DelVal;
                }
                break;

            case 15: // Delete value: T00+T10+T01+T11
                z = DelVal;
                break;

            //-------------------------
            // Smooth delete value chop variants
            // Calculation of z is identical, though the chopping is different
            case 16: // 0: Default
                if ((T00 == T10) && (T00 == T01) && (T00 == T11))
                {
                    z = T00;
                }
                else
                {
                    z = (1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 +
                        (1 - dx) * dy * T01 + dx * dy * T11;
                }
                break;

            case 17: // 1: Delete value: T00
                if (dx + dy < 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = (dx * (1 - dy) * T10 + (1 - dx) * dy * T01 + dx * dy * T11) /
                        (dx + dy - dx * dy);
                }
                break;

            case 18: // 2: Delete value: T10
                if (dx - dy >= 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + (1 - dx) * dy * T01 + dx * dy * T11) /
                        (1 - dx + dx * dy);
                }
                break;

            case 19: // 3: Delete value: T00+T10
                if (dy < 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * T01 + dx * T11);
                }
                break;

            case 20: // 4: Delete value: T01
                if (dx - dy < -0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 + dx * dy * T11) /
                        (1 - dy + dx * dy);
                }
                break;

            case 21: // 5: Delete value: T00+T01
                if (dx < 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dy) * T10 + dy * T11;
                }
                break;

            case 22: // 6: Delete value: T10+T01
                if ((dx + dy >= 0.5) && (dx + dy < 1.5))
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * dy * T11) /
                        (1 - dx - dy + 2 * dx * dy);
                }
                break;

            case 23: // 7: Delete value: T00+T10+T01
                if (dx + dy < 1.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = T11;
                }
                break;

            case 24: // 8: Delete value: T11
                if (dx + dy >= 1.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = ((1 - dx) * (1 - dy) * T00 + dx * (1 - dy) * T10 +
                         (1 - dx) * dy * T01) /
                        (1 - dx * dy);
                }
                break;

            case 25: // 9: Delete value: T00+T11
                if ((dx - dy >= -0.5) && (dx - dy < 0.5))
                {
                    z = DelVal;
                }
                else
                {
                    z = (dx * (1 - dy) * T10 + (1 - dx) * dy * T01) /
                        (dx + dy - 2 * dx * dy);
                }
                break;

            case 26: // 10: Delete value: T10+T11
                if (dx >= 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dy) * T00 + dy * T01;
                }
                break;

            case 27: // 11: Delete value: T00+T10+T11
                if (dx - dy > -0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = T01;
                }
                break;

            case 28: // 12: Delete value: T01+T11
                if (dy >= 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = (1 - dx) * T00 + dx * T10;
                }
                break;

            case 29: // 13: Delete value: T00+T01+T11
                if (dx - dy < 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = T10;
                }
                break;

            case 30: // 14: Delete value: T10+T01+T11
                if (dx + dy > 0.5)
                {
                    z = DelVal;
                }
                else
                {
                    z = T00;
                }
                break;

            case 31: // 15: Delete value: T00+T10+T01+T11
                z = DelVal;
                break;

            default:
                z = DelVal;
                break;
            }
            CircularValueHandler.ToCircular(CircularType, ref z);
            return(z);
        }