Пример #1
0
//============================================================================
//      NTargetNetwork::URLResponseCancel : Cancel a URL response.
//----------------------------------------------------------------------------
void NTargetNetwork::URLResponseCancel(NURLResponseRef theResponse)
{


	// dair, to do
	NN_LOG("NTargetNetwork::URLResponseCancel not implemented!");
}
Пример #2
0
//============================================================================
//		NCFNumber::SetObject : Set the object.
//----------------------------------------------------------------------------
bool NCFNumber::SetObject(CFNumberRef cfObject, bool takeOwnership)
{	NCFObject		theObject(cfObject, takeOwnership);
	float64_t		valueFloat64;
	float32_t		valueFloat32;
	int64_t			valueInt64;
	bool			isValid;



	// Get the state we need
	isValid = (cfObject != NULL);
	SetInt8(0);



	// Set the object
	if (isValid)
		{
		if (CFNumberGetValue(     cfObject, kCFNumberLongLongType, &valueInt64))
			SetInt64(valueInt64);
		
		else if (CFNumberGetValue(cfObject, kCFNumberFloatType,    &valueFloat32))
			SetFloat32(valueFloat32);
		
		else if (CFNumberGetValue(cfObject, kCFNumberDoubleType,   &valueFloat64))
			SetFloat64(valueFloat64);

		else
			NN_LOG("Unable to convert CFNumber to NNumber");
		}

	return(isValid);
}
Пример #3
0
//============================================================================
//		NCFNumber::GetObject : Get the object.
//----------------------------------------------------------------------------
NCFObject NCFNumber::GetObject(void) const
{	float64_t		valueFloat64;
	float32_t		valueFloat32;
	int64_t			valueInt64;
	NCFObject		theObject;



	// Get the object
	switch (GetPrecision()) {
		case kNPrecisionInt8:
		case kNPrecisionInt16:
		case kNPrecisionInt32:
		case kNPrecisionInt64:
			valueInt64 = GetInt64();
			theObject.SetObject(CFNumberCreate(kCFAllocatorNano, kCFNumberLongLongType, &valueInt64));
			break;
		
		case kNPrecisionFloat32:
			valueFloat32 = GetFloat32();
			theObject.SetObject(CFNumberCreate(kCFAllocatorNano, kCFNumberFloatType,    &valueFloat32));
			break;
		
		case kNPrecisionFloat64:
			valueFloat64 = GetFloat64();
			theObject.SetObject(CFNumberCreate(kCFAllocatorNano, kCFNumberDoubleType,   &valueFloat64));
			break;
		
		default:
			NN_LOG("Unable to convert '%@' to CFNumber", GetString());
			break;
		}

	return(theObject);
}
Пример #4
0
//============================================================================
//      NTargetNetwork::SocketSetOption : Set a socket option.
//----------------------------------------------------------------------------
NStatus NTargetNetwork::SocketSetOption(NSocketRef theSocket, NSocketOption theOption, int32_t theValue)
{	int			valueInt;
	NStatus		theErr;



	// Validate our parameters
	NN_ASSERT(theSocket->nativeSocket != kSocketHandleInvalid);



	// Get the state we need
	theErr = kNErrNotSupported;



	// Set the option
	switch (theOption) {
		case kNSocketNoDelay:
			valueInt = (theValue != 0) ? 1 : 0;

			if (setsockopt(theSocket->nativeSocket, IPPROTO_TCP, TCP_NODELAY, &valueInt, sizeof(valueInt)) == 0)
				theErr = kNoErr;
			break;

		default:
			NN_LOG("Unknown option: %d", theOption);
			break;
		}
	
	return(theErr);
}
Пример #5
0
//============================================================================
//      NTargetNetwork::ServiceBrowserDestroy : Destroy a service browser.
//----------------------------------------------------------------------------
void NTargetNetwork::ServiceBrowserDestroy(NServiceBrowserRef theBrowser)
{


	// dair, to do
	NN_LOG("NTargetNetwork::ServiceBrowserDestroy not implemented!");
}
Пример #6
0
//============================================================================
//      NTargetNetwork::URLResponseDestroy : Destroy a URL response.
//----------------------------------------------------------------------------
void NTargetNetwork::URLResponseDestroy(NURLResponseRef theResponse)
{


	// dair, to do
	NN_LOG("NTargetNetwork::URLResponseDestroy not implemented!");
}
Пример #7
0
//============================================================================
//		NCGShading::UpdateShading : Update the shading.
//----------------------------------------------------------------------------
void NCGShading::UpdateShading(void) const
{	CGColorSpaceRef		cgColorSpace;



	// Validate our state
	NN_ASSERT(!mShading.IsValid());



	// Create the new shading
	cgColorSpace = NCGColor::GetDeviceRGB();

	switch (mMode) {
		case kShadingNone:
			ResetShading();
			break;

		case kShadingLinear:
			mShading.SetObject(CGShadingCreateAxial( cgColorSpace, ToCG(mStartPoint), ToCG(mEndPoint), mEvaluate, mStartExtend, mEndExtend));
			break;

		case kShadingRadial:
			mShading.SetObject(CGShadingCreateRadial(cgColorSpace, ToCG(mStartPoint), mStartRadius, ToCG(mEndPoint), mEndRadius, mEvaluate, mStartExtend, mEndExtend));
			break;

		default:
			NN_LOG("Unknown shading mode: %d", mMode);
			break;
		}
}
Пример #8
0
//============================================================================
//		NNumber::IsInteger : Is the number an integer?
//----------------------------------------------------------------------------
bool NNumber::IsInteger(void) const
{	bool	isInteger;



	// Check the type
	switch (mPrecision) {
		case kNPrecisionInt8:
		case kNPrecisionInt16:
		case kNPrecisionInt32:
		case kNPrecisionInt64:
			isInteger = true;
			break;
		
		case kNPrecisionFloat32:
		case kNPrecisionFloat64:
			isInteger = false;
			break;
		
		default:
			NN_LOG("Unknown precision: %d", mPrecision);
			isInteger = false;
			break;
		}
	
	return(isInteger);
}
Пример #9
0
//============================================================================
//      NTargetNetwork::SocketGetOption : Get a socket option.
//----------------------------------------------------------------------------
int32_t NTargetNetwork::SocketGetOption(NSocketRef theSocket, NSocketOption theOption)
{	socklen_t		valueSize;
	int				valueInt;
	int32_t			theValue;



	// Validate our parameters
	NN_ASSERT(theSocket->nativeSocket != kSocketHandleInvalid);



	// Get the state we need
	theValue = 0;



	// Get the option
	switch (theOption) {
		case kNSocketNoDelay:
			valueInt  = 0;
			valueSize = sizeof(valueInt);

			if (getsockopt(theSocket->nativeSocket, IPPROTO_TCP, TCP_NODELAY, &valueInt, &valueSize) == 0)
				theValue = (valueInt != 0);
			break;

		default:
			NN_LOG("Unknown option: %d", theOption);
			break;
		}
	
	return(theValue);
}
Пример #10
0
//============================================================================
//      NTargetNetwork::ServiceAdvertiserCreate : Create a service advertiser.
//----------------------------------------------------------------------------
NServiceAdvertiserRef NTargetNetwork::ServiceAdvertiserCreate(const NString &serviceType, uint16_t thePort, const NString &theName)
{


	// dair, to do
	NN_LOG("NTargetNetwork::ServiceAdvertiserCreate not implemented!");
	return(NULL);
}
Пример #11
0
//============================================================================
//      NTargetNetwork::ServicesAvailable : Are network services available?
//----------------------------------------------------------------------------
bool NTargetNetwork::ServicesAvailable(void)
{


	// dair, to do
	NN_LOG("NTargetNetwork::ServicesAvailable not implemented!");
	return(false);
}
Пример #12
0
//============================================================================
//      NTargetNetwork::ServiceBrowserCreate : Create a service browser.
//----------------------------------------------------------------------------
NServiceBrowserRef NTargetNetwork::ServiceBrowserCreate(const NString &serviceType, const NNetworkBrowserEventFunctor &theFunctor)
{


	// dair, to do
	NN_LOG("NTargetNetwork::ServiceBrowserCreate not implemented!");
	return(NULL);
}
Пример #13
0
//============================================================================
//		TSocketClient::SocketDidClose : The socket has closed.
//----------------------------------------------------------------------------
void TSocketClient::SocketDidClose(NSocket * /*theSocket*/, NStatus theErr)
{


	// Log the event
	if (theErr != kNoErr)
		NN_LOG("TSocketClient closed with error: %d", theErr);
}
Пример #14
0
//============================================================================
//      NTargetNetwork::URLResponseCreate : Create a URL response.
//----------------------------------------------------------------------------
NURLResponseRef NTargetNetwork::URLResponseCreate(NURLResponse *theResponse)
{


	// dair, to do
	NN_LOG("NTargetNetwork::URLResponseCreate not implemented!");
	return(0);
}
Пример #15
0
//============================================================================
//      NTargetNetwork::SocketCanWrite : Can a socket be written to?
//----------------------------------------------------------------------------
bool NTargetNetwork::SocketCanWrite(NSocketRef theSocket)
{


	// dair, to do
	NN_LOG("NTargetNetwork::SocketCanWrite not implemented!");
	return(false);
}
Пример #16
0
//============================================================================
//      NTargetNetwork::IsReachable : Is a URL reachable?
//----------------------------------------------------------------------------
bool NTargetNetwork::IsReachable(const NURL &theURL)
{


	// dair, to do
	NN_LOG("NTargetNetwork::IsReachable not implemented!");
	return(false);
}
Пример #17
0
//============================================================================
//		NUnicodeParser::RemoveBOM : Remove a BOM prefix.
//----------------------------------------------------------------------------
void NUnicodeParser::RemoveBOM(NData &theData, NStringEncoding theEncoding) const
{   NStringEncoding		bomEncoding;
    NRange				theBOM;



    // Validate our parameters
    NN_ASSERT(NStringEncoder::IsEncodingUTF(theEncoding));
    NN_UNUSED(theEncoding);



    // Get the state we need
    bomEncoding = GetBOM(theData, theBOM);
    if (!theBOM.IsEmpty())
        theData.RemoveData(theBOM);



    // Validate the encoding
    //
    // Endian-specific BOMs should match the format we expected.
    switch (bomEncoding) {
    case kNStringEncodingInvalid:
        // No BOM
        break;

    case kNStringEncodingUTF8:
        NN_ASSERT(theEncoding == kNStringEncodingUTF8);
        break;

    case kNStringEncodingUTF16BE:
        NN_ASSERT(theEncoding == kNStringEncodingUTF16 || theEncoding == kNStringEncodingUTF16BE);
        break;

    case kNStringEncodingUTF16LE:
        NN_ASSERT(theEncoding == kNStringEncodingUTF16 || theEncoding == kNStringEncodingUTF16LE);
        break;

    case kNStringEncodingUTF32BE:
        NN_ASSERT(theEncoding == kNStringEncodingUTF32 || theEncoding == kNStringEncodingUTF32BE);
        break;

    case kNStringEncodingUTF32LE:
        NN_ASSERT(theEncoding == kNStringEncodingUTF32 || theEncoding == kNStringEncodingUTF32LE);
        break;

    default:
        NN_LOG("Invalid encoding: %d", theEncoding);
        break;
    }
}
Пример #18
0
//============================================================================
//		NCGImage::GetBitmapInfo : Get a CGBitmapInfo.
//----------------------------------------------------------------------------
CGBitmapInfo NCGImage::GetBitmapInfo(NImageFormat theFormat)
{	CGBitmapInfo	bitmapInfo;



	// Get the bitmap info
	bitmapInfo = 0;
	
	switch (theFormat) {
		case kNImageFormat_RGB_888:
			bitmapInfo = kCGBitmapByteOrder32Big	| kCGImageAlphaNone;
			break;

		case kNImageFormat_BGR_888:
			bitmapInfo = kCGBitmapByteOrder32Little	| kCGImageAlphaNone;
			break;

		case kNImageFormat_RGBX_8888:
			bitmapInfo = kCGBitmapByteOrder32Big	| kCGImageAlphaNoneSkipLast;
			break;

		case kNImageFormat_RGBA_8888:
			bitmapInfo = kCGBitmapByteOrder32Big	| kCGImageAlphaPremultipliedLast;
			break;

		case kNImageFormat_XRGB_8888:
			bitmapInfo = kCGBitmapByteOrder32Big	| kCGImageAlphaNoneSkipFirst;
			break;

		case kNImageFormat_ARGB_8888:
			bitmapInfo = kCGBitmapByteOrder32Big	| kCGImageAlphaPremultipliedFirst;
			break;

		case kNImageFormat_BGRX_8888:
			bitmapInfo = kCGBitmapByteOrder32Little	| kCGImageAlphaNoneSkipFirst;
			break;

		case kNImageFormat_BGRA_8888:
			bitmapInfo = kCGBitmapByteOrder32Little	| kCGImageAlphaPremultipliedFirst;
			break;

		default:
			NN_LOG("Unknown image format: %d", theFormat);
			bitmapInfo = 0;
			break;
		}
	
	return(bitmapInfo);
}
Пример #19
0
//============================================================================
//		NUnicodeParser::AddBOM : Add a BOM prefix.
//----------------------------------------------------------------------------
void NUnicodeParser::AddBOM(NData &theData, NStringEncoding theEncoding) const
{   NRange		theRange;



    // Validate our parameters
    NN_ASSERT(NStringEncoder::IsEncodingUTF(theEncoding));
    NN_ASSERT(GetBOM(theData, theRange) == kNStringEncodingInvalid);

    (void) theRange;



    // Add the BOM
    switch (theEncoding) {
    case kNStringEncodingUTF8:
        AddBOMToUTF8(theData);
        break;

    case kNStringEncodingUTF16:
        AddBOMToUTF16(theData, kNEndianNative);
        break;

    case kNStringEncodingUTF16BE:
        AddBOMToUTF16(theData, kNEndianBig);
        break;

    case kNStringEncodingUTF16LE:
        AddBOMToUTF16(theData, kNEndianLittle);
        break;

    case kNStringEncodingUTF32:
        AddBOMToUTF32(theData, kNEndianNative);
        break;

    case kNStringEncodingUTF32BE:
        AddBOMToUTF32(theData, kNEndianBig);
        break;

    case kNStringEncodingUTF32LE:
        AddBOMToUTF16(theData, kNEndianLittle);
        break;

    default:
        NN_LOG("Invalid encoding: %d", theEncoding);
        break;
    }
}
Пример #20
0
//============================================================================
//		NBroadcaster::AddListener : Add a listener.
//----------------------------------------------------------------------------
void NBroadcaster::AddListener(NListener *theListener)
{


	// Validate our parameters
	NN_ASSERT(theListener != NULL);
	
	if (NN_DEBUG && theListener->IsListeningTo(this))
		NN_LOG("NBroadcaster already being listened to by %p", theListener);



	// Add the listener
	mListeners[theListener] = 1;
	
	theListener->AddBroadcaster(this);
}
Пример #21
0
//============================================================================
//		NTargetThread::ThreadInvokeMain : Invoke the main thread.
//----------------------------------------------------------------------------
void NTargetThread::ThreadInvokeMain(const NFunctor &theFunctor)
{	NFunctor				invokeFunctor;
	NSemaphore				theSemaphore;
// dair, to do
//	CFAbsoluteTime			fireTime;
//	CFRunLoopTimerRef		cfTimer;
	bool					wasDone;



	// Invoke the functor
	if (ThreadIsMain())
		theFunctor();


	// Pass it to the main thread
	//
	// An invoker is used to invoke the functor then set our semaphore.
	//
	// The invoker is executed by the main thread, via InvokeMainThreadFunctors, either
	// due to the main thread being blocked in ThreadSleep or due to the event loop
	// running as normal and executing our timer.
	else
		{
		// Save the functor
		gMainThreadFunctors.PushBack(BindFunction(InvokeMainThreadFunctor, theFunctor, &theSemaphore));


// dair, to do
NN_LOG("NTargetThread::ThreadInvokeMain skipping runloop!");
/*
		// Schedule the timer
		fireTime = CFRunLoopGetNextTimerFireDate(CFRunLoopGetMain(), kCFRunLoopCommonModes);
		cfTimer  = CFRunLoopTimerCreate(kCFAllocatorNano, fireTime, 0.0f, 0, 0, MainThreadFunctorsTimer, NULL);

		CFRunLoopAddTimer(CFRunLoopGetMain(), cfTimer, kCFRunLoopCommonModes);
		CFSafeRelease(cfTimer);
*/


		// Wait for the functor to be processed
		wasDone = theSemaphore.Wait();
		NN_ASSERT(wasDone);
		}
}
Пример #22
0
//============================================================================
//		NNumber::GetString : Get the number as a string.
//----------------------------------------------------------------------------
NString NNumber::GetString(void) const
{	NString		valueText;



	// Get the string
	switch (mPrecision) {
		case kNPrecisionInt8:
		case kNPrecisionInt16:
		case kNPrecisionInt32:
		case kNPrecisionInt64:
			valueText.Format("%lld", mValue.integer);
			break;
			
		case kNPrecisionFloat32:
		case kNPrecisionFloat64:
			if (NTargetPOSIX::is_nan(mValue.real))
				valueText = kNStringNaN;

			else if (NTargetPOSIX::is_inf(mValue.real))
				valueText = (mValue.real < 0.0) ? kNStringInfinityNeg : kNStringInfinityPos;

			else if (NMathUtilities::IsZero(mValue.real))
				valueText = kNStringZero;

			else
				{
				if (mPrecision == kNPrecisionFloat32)
					valueText.Format(kFormatFloat32, (Float32) mValue.real);
				else
					valueText.Format(kFormatFloat64,           mValue.real);
				}
			break;

		default:
			NN_LOG("Unknown precision: %d", mPrecision);
			valueText = kNStringZero;
			break;
		}

	return(valueText);
}
Пример #23
0
//============================================================================
//		NUnicodeParser::Parse : Parse some data.
//----------------------------------------------------------------------------
void NUnicodeParser::Parse(const NData &theData, NStringEncoding theEncoding)
{   NRange		theRange;



    // Validate our parameters
    NN_ASSERT(NStringEncoder::IsEncodingUTF(theEncoding));



    // Set the value
    mData     = theData;
    mEncoding = theEncoding;

    (void) GetBOM(mData, theRange);



    // Identify the code points
    switch (mEncoding) {
    case kNStringEncodingUTF8:
        mCodePoints = GetCodePointsUTF8(theRange);
        break;

    case kNStringEncodingUTF16:
    case kNStringEncodingUTF16BE:
    case kNStringEncodingUTF16LE:
        mCodePoints = GetCodePointsUTF16(theRange);
        break;

    case kNStringEncodingUTF32:
    case kNStringEncodingUTF32BE:
    case kNStringEncodingUTF32LE:
        mCodePoints = GetCodePointsUTF32(theRange);
        break;

    default:
        NN_LOG("Invalid encoding: %d", theEncoding);
        break;
    }
}
Пример #24
0
//============================================================================
//		NDataEncoder::Decode : Decode from text.
//----------------------------------------------------------------------------
NData NDataEncoder::Decode(const NString &theValue, NDataEncoding theEncoding)
{	NData	theResult;



	// Decode the string
	switch (theEncoding) {
		case kNDataEncodingHex:
			theResult = Hex_Decode(theValue);
			break;

		case kNDataEncodingB64:
			theResult = B64_Decode(theValue);
			break;

		default:
			NN_LOG("Unknown encoding: %d", theEncoding);
			break;
		}
	
	return(theResult);
}
Пример #25
0
//============================================================================
//		NDataEncoder::Encode : Encode to text.
//----------------------------------------------------------------------------
NString NDataEncoder::Encode(const NData &theValue, NDataEncoding theEncoding)
{	NString		theResult;



	// Encode the data
	switch (theEncoding) {
		case kNDataEncodingHex:
			theResult = Hex_Encode(theValue);
			break;

		case kNDataEncodingB64:
			theResult = B64_Encode(theValue);
			break;

		default:
			NN_LOG("Unknown encoding: %d", theEncoding);
			break;
		}
	
	return(theResult);
}
Пример #26
0
static void DumpBinary(void)
{	NDataEncoder	theEncoder;
	NFile			theFile;
	NString			theText;
	NData			theData;



	// Create the binary .plist
	theFile = NFileUtilities::GetTemporaryFile("binary.plist");
	NFileUtilities::SetFileText(theFile, kPropertyListXML);

	NTask::Execute("/usr/bin/plutil", "-convert", "binary1", theFile.GetPath().GetUTF8());



	// Dump it
	theData = NFileUtilities::GetFileData(theFile);
	theText = theEncoder.Encode(theData, kNDataEncodingHex);
	theFile.Delete();

	NN_LOG("\nstatic const NString kPropertyListBinary					=	\"%@\";\n", theText);
}
Пример #27
0
//============================================================================
//		NBroadcaster::RemoveListener : Remove a listener.
//----------------------------------------------------------------------------
void NBroadcaster::RemoveListener(NListener *theListener)
{	NBroadcastStateListIterator		theIter;



	// Validate our parameters
	NN_ASSERT(theListener != NULL);

	if (NN_DEBUG && !theListener->IsListeningTo(this))
		NN_LOG("NBroadcaster wasn't being listened to by %p", theListener);



	// Remove the listener
	mListeners.erase(theListener);

	theListener->RemoveBroadcaster(this);



	// Update our state
	for (theIter = mBroadcasts.begin(); theIter != mBroadcasts.end(); theIter++)
		(*theIter)->theRecipients.erase(theListener);
}
Пример #28
0
//============================================================================
//		NNumber::Compare : Compare the value.
//----------------------------------------------------------------------------
NComparison NNumber::Compare(const NNumber &theValue) const
{	Float64				valueFloat64_1, valueFloat64_2;
	Float32				valueFloat32_1, valueFloat32_2;
	SInt64				valueInt64_1,  valueInt64_2;
	NComparison			theResult;



	// Compare equal types
	if (mPrecision == theValue.mPrecision || (IsInteger() && theValue.IsInteger()))
		{
		switch (mPrecision) {
			case kNPrecisionInt8:
			case kNPrecisionInt16:
			case kNPrecisionInt32:
			case kNPrecisionInt64:
				theResult = GetComparison(mValue.integer, theValue.mValue.integer);
				break;
			
			case kNPrecisionFloat32:
				valueFloat32_1 = (Float32)          mValue.real;
				valueFloat32_2 = (Float32) theValue.mValue.real;
				theResult      = GetComparison(valueFloat32_1, valueFloat32_2);
				break;

			case kNPrecisionFloat64:
				theResult = GetComparison(mValue.real, theValue.mValue.real);
				break;

			default:
				NN_LOG("Unknown precision: %d", mPrecision);
				theResult = kNCompareLessThan;
				break;
			}
		}


	// Compare dis-similar types
	else
		{
		switch (mPrecision) {
			case kNPrecisionInt8:
			case kNPrecisionInt16:
			case kNPrecisionInt32:
			case kNPrecisionInt64:
				valueInt64_1 =          GetSInt64();
				valueInt64_2 = theValue.GetSInt64();
				theResult    = GetComparison(valueInt64_1, valueInt64_2);
				break;

			case kNPrecisionFloat32:
				valueFloat32_1 =          GetFloat32();
				valueFloat32_2 = theValue.GetFloat32();
				theResult      = GetComparison(valueFloat32_1, valueFloat32_2);
				break;

			case kNPrecisionFloat64:
				valueFloat64_1 =          GetFloat64();
				valueFloat64_2 = theValue.GetFloat64();
				theResult      = GetComparison(valueFloat64_1, valueFloat64_2);
				break;

			default:
				NN_LOG("Unknown precision: %d", mPrecision);
				theResult = kNCompareLessThan;
				break;
			}
		}

	return(theResult);
}
Пример #29
0
//============================================================================
//      NGeometryUtilities::GetPointOnLine : Get a point on a line.
//----------------------------------------------------------------------------
template<class T> NPointT<T> NGeometryUtilities::GetPointOnLine(const std::vector< NPointT<T> > &thePoints, T theOffset)
{	T				theLength, intersectAt, segmentStart, segmentEnd;
	T				dx, dy, theDelta;
	NIndex			n, numPoints;
	NPointT<T>		theResult;



	// Validate our parameters
	NN_ASSERT(thePoints.size() >= 2);
	NN_ASSERT(theOffset        >= 0.0 && theOffset <= 1.0);



	// Get the state we need
	numPoints   = (NIndex) thePoints.size();
	theLength   = GetLength(thePoints);
	intersectAt = theLength * theOffset;



	// Find the intersection point
	//
	// To calculate the intersection we need to calculate the intersection
	// as if the line was entirely straight (intersectAt), and then re-walk
	// the line to determine which segment (and where in that segment) the
	// intersection point occurs.
	segmentStart = 0.0;
	segmentEnd   = 0.0;

	for (n = 0; n < (numPoints-1); n++)
		{
		// Identify the bounds of this segment
		dx = (thePoints[n+1].x - thePoints[n].x);
		dy = (thePoints[n+1].y - thePoints[n].y);
		
		theLength    = sqrt((dx * dx) + (dy * dy));
		segmentStart = segmentEnd;
		segmentEnd  += theLength;
		
		
		// Stop once we find the intersecting segment
		//
		// By calculating the %ge offset of the intersection within this
		// segment, we can determine how much of the segment delta to use
		// in order to find the location of the intersection.
		if (intersectAt <= segmentEnd)
			{
			theDelta    = (intersectAt - segmentStart) / (segmentEnd - segmentStart);
			theResult.x = (thePoints[n].x + (dx * theDelta));
			theResult.y = (thePoints[n].y + (dy * theDelta));
			
			return(theResult);
			}
		}



	// Handle failure
	NN_LOG("Unable to find intersection at offset %g", theOffset);
	return(theResult);
}
Пример #30
0
//=============================================================================
//		NGeometryUtilities::ClipLineToRectangle : Clip a line to a rectangle.
//-----------------------------------------------------------------------------
//		Note : Clips using Cohen-Sutherland.
//-----------------------------------------------------------------------------
template<class T> NGeometryComparison NGeometryUtilities::ClipLineToRectangle(	const              NRectangleT<T> &theRect,
																				const std::vector< NPointT<T> >   &theInput,
																					  std::vector< NPointT<T> >   &theOutput)
{	T						dx, dy, minX, maxX, minY, maxY;
	NBitfield				code0, code1, codeOut;
	NPointT<T>				p0, p1, pointOut;
	NGeometryComparison		theResult;



	// Get the state we need
	p0 = theInput[0];
	p1 = theInput[1];

	code0 = GetClipCode(theRect, p0);
	code1 = GetClipCode(theRect, p1);



	// Both points are outside
	if ((code0 & code1) != 0)
		{
		theOutput.clear();
		return(kNGeometryOutside);
		}



	// Both points are inside
	else if ((code0 | code1) == 0)
		{
		theOutput = theInput;
		return(kNGeometryInside);
		}



	// Intersection
	//
	// We pick an exterior point, then clip the segment to an edge.
	if (code0 != 0)
		{
		codeOut  = code0;
		pointOut = p0;
		}
	else
		{
		codeOut  = code1;
		pointOut = p1;
		}

	dx = p1.x - p0.x;
	dy = p1.y - p0.y;
		
	minX = theRect.GetMinX();
	maxX = theRect.GetMaxX();
		
	minY = theRect.GetMinY();
	maxY = theRect.GetMaxY();



	// Split line at top of rectangle
	if (codeOut & kNGeometryClipTop)
		{
		pointOut.x = p0.x + (dx * ((maxY - p0.y) / dy));
		pointOut.y = maxY;
		}
			
	// Split line at bottom of rectangle
	else if (codeOut & kNGeometryClipBottom)
		{
		pointOut.x = p0.x + (dx * ((minY - p0.y) / dy));
		pointOut.y = minY;
		}
		
	// Split line at right edge of rectangle
	else if (codeOut & kNGeometryClipRight)
		{
		pointOut.x = maxX;
		pointOut.y = p0.y + (dy * ((maxX - p0.x) / dx));
		}
			
	// Split line at left edge of rectangle
	else if (codeOut & kNGeometryClipLeft)
		{
		pointOut.x = minX;
		pointOut.y = p0.y + (dy * ((minX - p0.x) / dx));
		}
		
	else
		NN_LOG("Invalid codeOut: %d", codeOut);



	// Clip the new segment
	if (codeOut == code0)
		theResult = ClipLineToRectangle(theRect, vector(pointOut, p1), theOutput);
	else
		theResult = ClipLineToRectangle(theRect, vector(p0, pointOut), theOutput);



	// Update the result
	//
	// Since we know we had an intersection with one of the rectangle edges,
	// a result of inside is actually an intersection.
	//
		// A result of outside indicates the line intersected an edge but didn't
	// encroach on the rectangle itself so that result remains.
	if (theResult == kNGeometryInside)
		theResult = kNGeometryIntersects;

	return(theResult);
}