<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Dictionary Says XYZ Key Doesn't Exist When It Does in Revit API Forum</title>
    <link>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4763283#M77880</link>
    <description>&lt;P&gt;Hello&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a dictionary where the keys are XYZ objects and the values are boolean. I am attempting to check if a key exists in the dictionary.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My Problem:&lt;/STRONG&gt; If the dictionary contains the key new XYZ(1,1,1) and I go to check if the dictionary contains this key using myDictionary.ContainsKey(new XYZ(1,1,1) it always returns false.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Why is this happening and how can I fix this? I am aware I am comparing doubles which requires a degree of tolerance but shouldn't the XYZ.Equals() class compensate for this like many other API's that contain vertex classes? Or am I doing something wrong?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;Dictionary&amp;lt;XYZ, bool&amp;gt; prevPnts =newDictionary&amp;lt;XYZ, bool&amp;gt;();
prevPnts[new XYZ(1,1,1)]=true;&lt;BR /&gt;&lt;BR /&gt;// Always says the pnt doesnt exist?&lt;BR /&gt;if(prevPnts.ContainsKey(new XYZ(1,1,1)))&lt;BR /&gt;    TaskDialog.Show("Contains");&lt;BR /&gt;elseTaskDialog.Show("NOT Contains");&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Mon, 20 Jan 2014 22:14:01 GMT</pubDate>
    <dc:creator>Anonymous</dc:creator>
    <dc:date>2014-01-20T22:14:01Z</dc:date>
    <item>
      <title>Dictionary Says XYZ Key Doesn't Exist When It Does</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4763283#M77880</link>
      <description>&lt;P&gt;Hello&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a dictionary where the keys are XYZ objects and the values are boolean. I am attempting to check if a key exists in the dictionary.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My Problem:&lt;/STRONG&gt; If the dictionary contains the key new XYZ(1,1,1) and I go to check if the dictionary contains this key using myDictionary.ContainsKey(new XYZ(1,1,1) it always returns false.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Why is this happening and how can I fix this? I am aware I am comparing doubles which requires a degree of tolerance but shouldn't the XYZ.Equals() class compensate for this like many other API's that contain vertex classes? Or am I doing something wrong?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;Dictionary&amp;lt;XYZ, bool&amp;gt; prevPnts =newDictionary&amp;lt;XYZ, bool&amp;gt;();
prevPnts[new XYZ(1,1,1)]=true;&lt;BR /&gt;&lt;BR /&gt;// Always says the pnt doesnt exist?&lt;BR /&gt;if(prevPnts.ContainsKey(new XYZ(1,1,1)))&lt;BR /&gt;    TaskDialog.Show("Contains");&lt;BR /&gt;elseTaskDialog.Show("NOT Contains");&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 20 Jan 2014 22:14:01 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4763283#M77880</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-01-20T22:14:01Z</dc:date>
    </item>
    <item>
      <title>Re: Dictionary Says XYZ Key Doesn't Exist When It Does</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4763313#M77881</link>
      <description>&lt;P&gt;Ok looks like the only solution is to make my own IEqualityComparer:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;         class XYZEqualityComparer : IEqualityComparer&amp;lt;XYZ&amp;gt;
        {
            public bool Equals(XYZ a, XYZ b)
            {
                if (Math.Abs(a.DistanceTo(b)) &amp;lt;= 0.05)
                    return true;
                
                return false;
            }


            public int GetHashCode(XYZ x)
            {
                int hash = 17;
                hash = hash * 23 + x.X.GetHashCode();
                hash = hash * 23 + x.Y.GetHashCode();
                hash = hash * 23 + x.Z.GetHashCode();
                return hash;
            }
        }

Dictionary&amp;lt;XYZ, bool&amp;gt; prevPnts = new Dictionary&amp;lt;XYZ, bool&amp;gt;(new XYZEqualityComparer());&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 20 Jan 2014 22:29:33 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4763313#M77881</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-01-20T22:29:33Z</dc:date>
    </item>
    <item>
      <title>Re: Dictionary Says XYZ Key Doesn't Exist When It Does</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4764257#M77882</link>
      <description>&lt;P&gt;Looks like you've got the best remedy there, nice work.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How is it performing on real world data though?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I ask because your hash algorithm is working on the output from the default dotNet hashing algorithm which is not likely to work unless you are checking the exact same values from the same source (i.e. add end points found in a CurveLoop into dictionary then check subsequent points found in same loop against dictionary). If you were to gather your points and then check points found in some other unrelated (but visually co-located) geometry you will likely miss some hits.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;A quick test indicates that doubles that are equal to around 18 significant digits or more will usually generate the same hash but for anything with less precision you will likely get different values and therefore no hits in the dictionary.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Revit calls anything equal down to 9 decimal places good enough and so is likely to give you XYZ points that it would report as being co-located but would generate completely different hashes using your algorithm.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Paste this into a fresh console app and you'll see what I mean.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;SPAN&gt;using&lt;/SPAN&gt;&amp;nbsp;System;
 
&lt;SPAN&gt;namespace&lt;/SPAN&gt;&amp;nbsp;DoubleHashingTest
{
	&lt;SPAN&gt;class&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;Program&lt;/SPAN&gt;
	{
		&lt;SPAN&gt;static&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;void&lt;/SPAN&gt;&amp;nbsp;Main(&lt;SPAN&gt;string&lt;/SPAN&gt;[]&amp;nbsp;args)
		{
			&lt;SPAN&gt;double&lt;/SPAN&gt;&amp;nbsp;a&amp;nbsp;&lt;SPAN&gt;=&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;224.5000000000&lt;/SPAN&gt;;
			&lt;SPAN&gt;double&lt;/SPAN&gt;&amp;nbsp;b&amp;nbsp;&lt;SPAN&gt;=&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;224.5000000001&lt;/SPAN&gt;;
 
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;WriteLine(&lt;SPAN&gt;"Almost&amp;nbsp;Equal?:&amp;nbsp;"&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;+&lt;/SPAN&gt;&amp;nbsp;(&lt;SPAN&gt;Math&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;Abs(a &lt;SPAN&gt;- &lt;/SPAN&gt;b)&amp;nbsp;&lt;SPAN&gt;&amp;lt;=&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;1.0e-9&lt;/SPAN&gt;)&lt;SPAN&gt;.&lt;/SPAN&gt;ToString());
			
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;WriteLine(&lt;SPAN&gt;"Hash&amp;nbsp;Code&amp;nbsp;A:&amp;nbsp;"&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;+&lt;/SPAN&gt;&amp;nbsp;a&lt;SPAN&gt;.&lt;/SPAN&gt;GetHashCode()&lt;SPAN&gt;.&lt;/SPAN&gt;ToString());
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;WriteLine(&lt;SPAN&gt;"Hash&amp;nbsp;Code&amp;nbsp;B:&amp;nbsp;"&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;+&lt;/SPAN&gt;&amp;nbsp;b&lt;SPAN&gt;.&lt;/SPAN&gt;GetHashCode()&lt;SPAN&gt;.&lt;/SPAN&gt;ToString());
			
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;WriteLine(&lt;SPAN&gt;"Hash&amp;nbsp;Code&amp;nbsp;A&amp;nbsp;(Rounded):&amp;nbsp;"&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;+&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;Math&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;Round(a,&lt;SPAN&gt;9&lt;/SPAN&gt;)&lt;SPAN&gt;.&lt;/SPAN&gt;GetHashCode()&lt;SPAN&gt;.&lt;/SPAN&gt;ToString());
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;WriteLine(&lt;SPAN&gt;"Hash&amp;nbsp;Code&amp;nbsp;B&amp;nbsp;(Rounded):&amp;nbsp;"&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;+&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN&gt;Math&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;Round(b,&amp;nbsp;&lt;SPAN&gt;9&lt;/SPAN&gt;)&lt;SPAN&gt;.&lt;/SPAN&gt;GetHashCode()&lt;SPAN&gt;.&lt;/SPAN&gt;ToString());
 
			&lt;SPAN&gt;Console&lt;/SPAN&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;ReadLine();
		}
	}
}&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'd suggest either rounding the components of each XYZ before adding to dictionary or simply modifying your hash function to round each component to something like 4 decimal places (depending on the accuracy you need) before generating its hash.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;public int GetHashCode(XYZ x)
            {
                int hash = 17;
                hash = hash * 23 + Math.Round(x.X,4).GetHashCode();
                hash = hash * 23 + Math.Round(x.Y,4).GetHashCode();
                hash = hash * 23 + Math.Round(x.Z,4).GetHashCode();
                return hash;
            }&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jan 2014 12:23:11 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/4764257#M77882</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2014-01-21T12:23:11Z</dc:date>
    </item>
    <item>
      <title>Re: Dictionary Says XYZ Key Doesn't Exist When It Does</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/5573516#M77883</link>
      <description>&lt;P&gt;Plese also see the same topic raised on stackoverflow:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://stackoverflow.com/questions/21245144/dictionary-says-key-doesnt-exist-when-it-does/29490262" target="_blank"&gt;http://stackoverflow.com/questions/21245144/dictionary-says-key-doesnt-exist-when-it-does/29490262&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Cheers,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Jeremy&lt;/P&gt;</description>
      <pubDate>Tue, 07 Apr 2015 11:18:13 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/dictionary-says-xyz-key-doesn-t-exist-when-it-does/m-p/5573516#M77883</guid>
      <dc:creator>jeremytammik</dc:creator>
      <dc:date>2015-04-07T11:18:13Z</dc:date>
    </item>
  </channel>
</rss>

