1. Cacti does the monitoring and somehow sends the data to nagios via passive checks
I think this is the best option, from the stand point of not having Nagios work overtime to poll the data. Depending on check times, and intervals, this could be an issue. But, this option would allow you to run the cacti poller, then have a script that would run right after the poller. This script would read a configuration file, or something, and then would submit passive checks to the Nagios Command Pipe. This way, you don't have nagios and the poller competing for processor, at least as much as they would in other senarios.
Plus, the only complication with this method is the configuration of the passive services and what cacti metrics are passed to nagios. The script would read the database, get the rrd file, read the value, format it and submit it to nagios.
I would suggest that the configration be easy. What I mean by that, you would have the host (same on both systems), the service, the Cacti DS_ID and the Cacti DS value. The DS value, would have to support some sort of calculation syntax, so that you could do simple calculations, IE, percent. Then the script would use the Cacti DS ID to look up the RRD file path, then call RRD, retrieve the values, process the defined calculations and finally submit the passive check to Nagios.
Not that I haven't thought about this in the past..