1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include "aqua/salmathutils.hxx" 32 33 #include <stdlib.h> 34 35 // ======================================================================= 36 37 // ======================================================================= 38 39 #define Swap( x, y ) { x ^= y; y ^= x; x ^= y; } 40 41 // ======================================================================= 42 43 // ======================================================================= 44 45 // Storage free swapping using XOR 46 47 void CSwap ( char &rX, char &rY ) 48 { 49 Swap( rX, rY ); 50 } // CSwap 51 52 // ----------------------------------------------------------------------- 53 54 // Storage free swapping using XOR 55 56 void UCSwap ( unsigned char &rX, unsigned char &rY ) 57 { 58 Swap( rX, rY ); 59 } // UCSwap 60 61 // ----------------------------------------------------------------------- 62 63 // Storage free swapping using XOR 64 65 void SSwap ( short &rX, short &rY ) 66 { 67 Swap( rX, rY ); 68 } // SSwap 69 70 // ----------------------------------------------------------------------- 71 72 // Storage free swapping using XOR 73 74 void USSwap ( unsigned short &rX, unsigned short &rY ) 75 { 76 Swap( rX, rY ); 77 } // USSwap 78 79 // ----------------------------------------------------------------------- 80 81 // Storage free swapping using XOR 82 83 void LSwap ( long &rX, long &rY ) 84 { 85 Swap( rX, rY ); 86 } // LSwap 87 88 // ----------------------------------------------------------------------- 89 90 // Storage free swapping using XOR 91 92 void ULSwap ( unsigned long &rX, unsigned long &rY ) 93 { 94 Swap( rX, rY ); 95 } // ULSwap 96 97 // ======================================================================= 98 99 // ======================================================================= 100 101 // ----------------------------------------------------------------------- 102 // 103 // This way of measuring distance is also called the "Manhattan distance." 104 // Manhattan distance takes advantage of the fact that the sum of the 105 // lengths of the three components of a 3D vector is a rough approxima- 106 // tion of the vector's length. 107 // 108 // ----------------------------------------------------------------------- 109 110 unsigned long Euclidian2Norm ( const LRectCoorVector pVec ) 111 { 112 unsigned long ndist = 0; 113 114 if ( pVec ) 115 { 116 long nDX = 0; 117 long nDY = 0; 118 long nDZ = 0; 119 unsigned long nMax = 0; 120 unsigned long nMed = 0; 121 unsigned long nMin = 0; 122 123 // Find |x'-x|, |y'-y|, and |z'-z| from (x,y,z) and (x',y',z') 124 125 nDX = pVec[1].x - pVec[0].x; 126 nDY = pVec[1].y - pVec[0].y; 127 nDZ = pVec[1].z - pVec[0].z; 128 129 nMax = (unsigned long)abs( nDX ); 130 nMed = (unsigned long)abs( nDY ); 131 nMin = (unsigned long)abs( nDZ ); 132 133 // Sort them (3 compares, 0-3 swaps) 134 135 if ( nMax < nMed ) 136 { 137 Swap( nMax, nMed ); 138 } // if 139 140 if ( nMax < nMin ) 141 { 142 Swap( nMax, nMin ); 143 } // if 144 145 // Approximate Euclidian distance: 146 // 147 // d = max + (11/32)*med + (1/4)*min 148 // 149 // with +/- 8% error, where the exact formulae for d is 150 // 151 // || (x',y',z') - (x,y,z) || = { |x'-x|^2 + |y'-y|^2 + |z'-z|^2 }^(1/2) 152 153 ndist = nMax + ( nMin >> 2UL ) 154 + ( ( ( nMed << 3UL ) + ( nMed << 1UL ) + nMed ) >> 5UL ); 155 } // if 156 157 return ndist; 158 } // RGBDistance 159 160 // ======================================================================= 161 162 // ======================================================================= 163 164