From 1802977b95d29198f27535b1b731d1180c083667 Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Wed, 11 Jan 2017 16:33:00 +0100 Subject: made new subdir --- tikzit/src/common/Edge.m | 757 ----------------------------------------------- 1 file changed, 757 deletions(-) delete mode 100644 tikzit/src/common/Edge.m (limited to 'tikzit/src/common/Edge.m') diff --git a/tikzit/src/common/Edge.m b/tikzit/src/common/Edge.m deleted file mode 100644 index 0c88e9d..0000000 --- a/tikzit/src/common/Edge.m +++ /dev/null @@ -1,757 +0,0 @@ -// -// Edge.m -// TikZiT -// -// Copyright 2010 Aleks Kissinger. All rights reserved. -// -// -// This file is part of TikZiT. -// -// TikZiT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// TikZiT is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with TikZiT. If not, see . -// - -#import "Edge.h" -#import "Shape.h" -#import "util.h" - -@implementation Edge - -- (id)init { - self = [super init]; - if (self) { - data = [[GraphElementData alloc] init]; - bend = 0; - inAngle = 135; - outAngle = 45; - bendMode = EdgeBendModeBasic; - weight = 0.4f; - dirty = YES; - source = nil; - target = nil; - edgeNode = nil; - sourceAnchor = @""; - targetAnchor = @""; - } - return self; -} - -- (id)initWithSource:(Node*)s andTarget:(Node*)t { - self = [self init]; - if (self) { - [self setSource:s]; - [self setTarget:t]; - edgeNode = nil; - - dirty = YES; - } - return self; -} - -- (BOOL)attachStyleFromTable:(NSArray*)styles { - NSString *style_name = [data propertyForKey:@"style"]; - - [self setStyle:nil]; - if (style_name == nil) return YES; - - for (EdgeStyle *s in styles) { - if ([[s name] compare:style_name]==NSOrderedSame) { - [self setStyle:s]; - return YES; - } - } - - // if we didn't find a style, fill in a default one -#if __has_feature(objc_arc) - style = [EdgeStyle defaultEdgeStyleWithName:style_name]; -#else - style = [[EdgeStyle defaultEdgeStyleWithName:style_name] retain]; -#endif - return NO; -} - -- (NSPoint) _findContactPointOn:(Node*)node at:(float)angle { - NSPoint rayStart = [node point]; - Shape *shape = [node shape]; - if (shape == nil) { - return rayStart; - } - - Transformer *shapeTrans = [node shapeTransformer]; - // rounding errors are a pain - NSRect searchArea = NSInsetRect([node boundsUsingShapeTransform:shapeTrans],-0.01,-0.01); - if (!NSPointInRect(rayStart, searchArea)) { - return rayStart; - } - - NSPoint rayEnd = findExitPointOfRay (rayStart, angle, searchArea); - - for (NSArray *path in [shape paths]) { - for (Edge *curve in path) { - NSPoint intersect; - [curve updateControls]; - if (lineSegmentIntersectsBezier (rayStart, rayEnd, - [shapeTrans toScreen:curve->tail], - [shapeTrans toScreen:curve->cp1], - [shapeTrans toScreen:curve->cp2], - [shapeTrans toScreen:curve->head], - &intersect)) { - // we just keep shortening the line - rayStart = intersect; - } - } - } - - return rayStart; -} - -- (NSPoint) _findTanFor:(NSPoint)pt usingSpanFrom:(float)t1 to:(float)t2 { - float dx = bezierInterpolate(t2, tail.x, cp1.x, cp2.x, head.x) - - bezierInterpolate(t1, tail.x, cp1.x, cp2.x, head.x); - float dy = bezierInterpolate(t2, tail.y, cp1.y, cp2.y, head.y) - - bezierInterpolate(t1, tail.y, cp1.y, cp2.y, head.y); - - // normalise - float len = sqrt(dx*dx+dy*dy); - if (len != 0) { - dx = (dx/len) * 0.1f; - dy = (dy/len) * 0.1f; - } - - return NSMakePoint (pt.x + dx, pt.y + dy); -} - -- (void)recalculateProperties { - dirty = YES; -} - -- (void)updateControls { - // check for external modification to the node locations - if (src.x != [source point].x || src.y != [source point].y || - targ.x != [target point].x || targ.y != [target point].y) - { - dirty = YES; - } - - if (dirty) { - src = [source point]; - targ = [target point]; - - float dx = (targ.x - src.x); - float dy = (targ.y - src.y); - - float angleSrc = 0.0f; - float angleTarg = 0.0f; - - if (bendMode == EdgeBendModeBasic) { - float angle = good_atan(dx, dy); - float bnd = (float)bend * (M_PI / 180.0f); - angleSrc = angle - bnd; - angleTarg = M_PI + angle + bnd; - } else if (bendMode == EdgeBendModeInOut) { - angleSrc = (float)outAngle * (M_PI / 180.0f); - angleTarg = (float)inAngle * (M_PI / 180.0f); - } - - tail = [self _findContactPointOn:source at:angleSrc]; - head = [self _findContactPointOn:target at:angleTarg]; - - // give a default distance for self-loops - float cdist = (dx==0.0f && dy==0.0f) ? weight : sqrt(dx*dx + dy*dy) * weight; - - cp1 = NSMakePoint(src.x + (cdist * cos(angleSrc)), - src.y + (cdist * sin(angleSrc))); - - cp2 = NSMakePoint(targ.x + (cdist * cos(angleTarg)), - targ.y + (cdist * sin(angleTarg))); - - mid = bezierInterpolateFull (0.5f, tail, cp1, cp2, head); - midTan = [self _findTanFor:mid usingSpanFrom:0.4f to:0.6f]; - - tailTan = [self _findTanFor:tail usingSpanFrom:0.0f to:0.1f]; - headTan = [self _findTanFor:head usingSpanFrom:1.0f to:0.9f]; - } - dirty = NO; -} - -- (void)convertBendToAngles { - float dx = (targ.x - src.x); - float dy = (targ.y - src.y); - float angle = good_atan(dx, dy); - float bnd = (float)bend * (M_PI / 180.0f); - - [self setOutAngle:round((angle - bnd) * (180.0f/M_PI))]; - [self setInAngle:round((M_PI + angle + bnd) * (180.0f/M_PI))]; - dirty = YES; -} - -- (void)convertAnglesToBend { - float dx = (targ.x - src.x); - float dy = (targ.y - src.y); - int angle = round((180.0f/M_PI) * good_atan(dx, dy)); - - // compute bend1 and bend2 to match inAngle and outAngle, resp. - int bend1, bend2; - - bend1 = outAngle - angle; - bend2 = angle - inAngle; - - [self setBend:(bend1 + bend2) / 2]; -} - -- (BOOL)isSelfLoop { - return (source == target); -} - -- (BOOL)isStraight { - return (bendMode == EdgeBendModeBasic && bend == 0); -} - -- (NSPoint)mid { - [self updateControls]; - return mid; -} - -- (NSPoint)midTan { - [self updateControls]; - return midTan; -} - -- (NSPoint)leftNormal { - [self updateControls]; - return NSMakePoint(mid.x + (mid.y - midTan.y), mid.y - (mid.x - midTan.x)); -} - -- (NSPoint)rightNormal { - [self updateControls]; - return NSMakePoint(mid.x - (mid.y - midTan.y), mid.y + (mid.x - midTan.x)); -} - -- (NSPoint)headTan { - [self updateControls]; - return headTan; -} - -- (NSPoint)leftHeadNormal { - [self updateControls]; - return NSMakePoint(headTan.x + (head.y - headTan.y), headTan.y - (head.x - headTan.x)); -} - -- (NSPoint)rightHeadNormal { - [self updateControls]; - return NSMakePoint(headTan.x - (head.y - headTan.y), headTan.y + (head.x - headTan.x)); -} - -- (NSPoint)tailTan { - [self updateControls]; - return tailTan; -} - -- (NSPoint)leftTailNormal { - [self updateControls]; - return NSMakePoint(tailTan.x + (tail.y - tailTan.y), tailTan.y - (tail.x - tailTan.x)); -} - -- (NSPoint)rightTailNormal { - [self updateControls]; - return NSMakePoint(tailTan.x - (tail.y - tailTan.y), tailTan.y + (tail.x - tailTan.x)); -} - -- (NSPoint) head { - [self updateControls]; - return head; -} - -- (NSPoint) tail { - [self updateControls]; - return tail; -} - -- (NSPoint)cp1 { - [self updateControls]; - return cp1; -} - -- (NSPoint)cp2 { - [self updateControls]; - return cp2; -} - -- (int)inAngle {return inAngle;} -- (void)setInAngle:(int)a { - inAngle = normaliseAngleDeg (a); - dirty = YES; -} - -- (int)outAngle {return outAngle;} -- (void)setOutAngle:(int)a { - outAngle = normaliseAngleDeg (a); - dirty = YES; -} - -- (EdgeBendMode)bendMode {return bendMode;} -- (void)setBendMode:(EdgeBendMode)mode { - bendMode = mode; - dirty = YES; -} - -- (int)bend {return bend;} -- (void)setBend:(int)b { - bend = normaliseAngleDeg (b); - dirty = YES; -} - -- (float)weight {return weight;} -- (void)setWeight:(float)w { -// if (source == target) weight = 1.0f; -// else weight = w; - weight = w; - dirty = YES; -} - -- (EdgeStyle*)style {return style;} -- (void)setStyle:(EdgeStyle*)s { - if (style != s) { -#if __has_feature(objc_arc) - style = s; -#else - [style release]; - style = [s retain]; -#endif - } -} - -- (Node*)source {return source;} -- (void)setSource:(Node *)s { - if (source != s) { - [source removeObserver:self - forKeyPath:@"style"]; - - if ([s style] == nil) { - [self setSourceAnchor:@"center"]; - } else if ([sourceAnchor isEqual:@"center"]) { - [self setSourceAnchor:@""]; - } - -#if __has_feature(objc_arc) - source = s; -#else - [source release]; - source = [s retain]; -#endif - - if (source==target) { - bendMode = EdgeBendModeInOut; - weight = 1.0f; - } - - [source addObserver:self - forKeyPath:@"style" - options:NSKeyValueObservingOptionNew - | NSKeyValueObservingOptionOld - context:NULL]; - - dirty = YES; - } -} - -- (Node*)target {return target;} -- (void)setTarget:(Node *)t { - if (target != t) { - [target removeObserver:self - forKeyPath:@"style"]; - - if ([t style] == nil) { - [self setTargetAnchor:@"center"]; - } else if ([targetAnchor isEqual:@"center"]) { - [self setTargetAnchor:@""]; - } - -#if __has_feature(objc_arc) - target = t; -#else - [target release]; - target = [t retain]; -#endif - - if (source==target) { - bendMode = EdgeBendModeInOut; - weight = 1.0f; - } - - [target addObserver:self - forKeyPath:@"style" - options:NSKeyValueObservingOptionNew - | NSKeyValueObservingOptionOld - context:NULL]; - - dirty = YES; - } -} - -- (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context - -{ - if ([keyPath isEqual:@"style"]) { - id oldStyle = [change objectForKey:NSKeyValueChangeOldKey]; - id newStyle = [change objectForKey:NSKeyValueChangeNewKey]; - id none = [NSNull null]; - if (object == source) { - if (oldStyle != none && newStyle == none) { - [self setSourceAnchor:@"center"]; - } else if (oldStyle == none && newStyle != none && - [sourceAnchor isEqual:@"center"]) { - [self setSourceAnchor:@""]; - } - } - if (object == target) { - if (oldStyle != none && newStyle == none) { - [self setTargetAnchor:@"center"]; - } else if (oldStyle == none && newStyle != none && - [targetAnchor isEqual:@"center"]) { - [self setTargetAnchor:@""]; - } - } - } - dirty = YES; -} - - -// edgeNode and hasEdgeNode use a bit of key-value observing to help the mac GUI keep up - -- (Node*)edgeNode {return edgeNode;} -- (void)setEdgeNode:(Node *)n { - [self willChangeValueForKey:@"edgeNode"]; - [self willChangeValueForKey:@"hasEdgeNode"]; - if (edgeNode != n) { - hasEdgeNode = (n != nil); -#if __has_feature(objc_arc) - edgeNode = n; -#else - [edgeNode release]; - edgeNode = [n retain]; -#endif - // don't set dirty bit, because control points don't need update - } - [self didChangeValueForKey:@"edgeNode"]; - [self didChangeValueForKey:@"hasEdgeNode"]; -} - -- (BOOL)hasEdgeNode { return hasEdgeNode; } -- (void)setHasEdgeNode:(BOOL)b { - [self willChangeValueForKey:@"edgeNode"]; - [self willChangeValueForKey:@"hasEdgeNode"]; - hasEdgeNode = b; - if (hasEdgeNode && edgeNode == nil) { - edgeNode = [[Node alloc] init]; - } - [self didChangeValueForKey:@"edgeNode"]; - [self didChangeValueForKey:@"hasEdgeNode"]; -} - -- (NSString*) sourceAnchor { return sourceAnchor; } -- (void)setSourceAnchor:(NSString *)_sourceAnchor{ - NSString *oldSourceAnchor = sourceAnchor; - if(_sourceAnchor != nil){ - sourceAnchor = [_sourceAnchor copy]; - }else{ - sourceAnchor = @""; - } -#if ! __has_feature(objc_arc) - [oldSourceAnchor release]; -#endif -} - -- (NSString*) targetAnchor { return targetAnchor; } -- (void)setTargetAnchor:(NSString *)_targetAnchor{ - NSString *oldTargetAnchor = targetAnchor; - if(_targetAnchor != nil){ - targetAnchor = [_targetAnchor copy]; - }else{ - targetAnchor = @""; - } -#if ! __has_feature(objc_arc) - [oldTargetAnchor release]; -#endif -} - -@synthesize data; -- (void) insertObject:(GraphElementProperty*)gep - inDataAtIndex:(NSUInteger)index { - [data insertObject:gep atIndex:index]; -} -- (void) removeObjectFromDataAtIndex:(NSUInteger)index { - [data removeObjectAtIndex:index]; -} -- (void) replaceObjectInDataAtIndex:(NSUInteger)index - withObject:(GraphElementProperty*)gep { - [data replaceObjectAtIndex:index withObject:gep]; -} - -- (void)updateData { - // unset everything to avoid redundant defs - [data unsetAtom:@"loop"]; - [data unsetProperty:@"in"]; - [data unsetProperty:@"out"]; - [data unsetAtom:@"bend left"]; - [data unsetAtom:@"bend right"]; - [data unsetProperty:@"bend left"]; - [data unsetProperty:@"bend right"]; - [data unsetProperty:@"looseness"]; - - if (style == nil) { - [data unsetProperty:@"style"]; - } else { - [data setProperty:[style name] forKey:@"style"]; - } - - if (bendMode == EdgeBendModeBasic && bend != 0) { - NSString *bendkey = @"bend right"; - int b = [self bend]; - if (b < 0) { - bendkey = @"bend left"; - b = -b; - } - - if (b == 30) { - [data setAtom:bendkey]; - } else { - [data setProperty:[NSString stringWithFormat:@"%d",b] forKey:bendkey]; - } - - } else if (bendMode == EdgeBendModeInOut) { - [data setProperty:[NSString stringWithFormat:@"%d",inAngle] - forKey:@"in"]; - [data setProperty:[NSString stringWithFormat:@"%d",outAngle] - forKey:@"out"]; - } - - // loop needs to come after in/out - if (source == target) [data setAtom:@"loop"]; - - if (![self isSelfLoop] && ![self isStraight]) - { - [data setProperty:[NSString stringWithFormat:@"%.2f",weight*2.5f] - forKey:@"looseness"]; - } -} - -- (void)setAttributesFromData { - bendMode = EdgeBendModeBasic; - - if ([data isAtomSet:@"bend left"]) { - [self setBend:-30]; - } else if ([data isAtomSet:@"bend right"]) { - [self setBend:30]; - } else if ([data propertyForKey:@"bend left"] != nil) { - NSString *bnd = [data propertyForKey:@"bend left"]; - [self setBend:-[bnd intValue]]; - } else if ([data propertyForKey:@"bend right"] != nil) { - NSString *bnd = [data propertyForKey:@"bend right"]; - [self setBend:[bnd intValue]]; - } else { - [self setBend:0]; - - if ([data propertyForKey:@"in"] != nil && [data propertyForKey:@"out"] != nil) { - bendMode = EdgeBendModeInOut; - [self setInAngle:[[data propertyForKey:@"in"] intValue]]; - [self setOutAngle:[[data propertyForKey:@"out"] intValue]]; - } - } - - if ([data propertyForKey:@"looseness"] != nil) { - weight = [[data propertyForKey:@"looseness"] floatValue] / 2.5f; - } else { - weight = ([self isSelfLoop]) ? 1.0f : 0.4f; - } -} - -- (void)setPropertiesFromEdge:(Edge*)e { - Node *en = [[e edgeNode] copy]; - [self setEdgeNode:en]; -#if ! __has_feature(objc_arc) - [en release]; -#endif - - GraphElementData *d = [[e data] copy]; - [self setData:d]; -#if ! __has_feature(objc_arc) - [d release]; -#endif - - [self setStyle:[e style]]; - [self setBend:[e bend]]; - [self setInAngle:[e inAngle]]; - [self setOutAngle:[e outAngle]]; - [self setBendMode:[e bendMode]]; - [self setWeight:[e weight]]; - - dirty = YES; // cached data will be recomputed lazily, rather than copied -} - -- (NSRect)boundingRect { - [self updateControls]; - NSRect bound = NSRectAround4Points(head, tail, cp1, cp2); - if ([self style] != nil) { - switch ([[self style] decorationStyle]) { - case ED_Arrow: - bound = NSRectWithPoint(bound, [self midTan]); - case ED_Tick: - bound = NSRectWithPoint(bound, [self leftNormal]); - bound = NSRectWithPoint(bound, [self rightNormal]); - case ED_None: - break; - } - if ([[self style] headStyle] != AH_None) { - bound = NSRectWithPoint(bound, [self leftHeadNormal]); - bound = NSRectWithPoint(bound, [self rightHeadNormal]); - } - if ([[self style] tailStyle] != AH_None) { - bound = NSRectWithPoint(bound, [self leftTailNormal]); - bound = NSRectWithPoint(bound, [self rightTailNormal]); - } - } - return bound; -} - -- (void) adjustWeight:(float)handle_dist withCourseness:(float)wcourseness { - float base_dist = NSDistanceBetweenPoints (src, targ); - if (base_dist == 0.0f) { - base_dist = 1.0f; - } - - [self setWeight:roundToNearest(wcourseness, handle_dist / base_dist)]; -} - -- (float) angleOf:(NSPoint)point relativeTo:(NSPoint)base { - float dx = point.x - base.x; - float dy = point.y - base.y; - return radiansToDegrees (good_atan(dx, dy)); -} - -- (void) moveCp1To:(NSPoint)point withWeightCourseness:(float)wc andBendCourseness:(int)bc forceLinkControlPoints:(BOOL)link { - [self updateControls]; - [self adjustWeight:NSDistanceBetweenPoints (point, src) withCourseness:wc]; - - float control_angle = [self angleOf:point relativeTo:src]; - if (bendMode == EdgeBendModeBasic) { - float base_angle = [self angleOf:targ relativeTo:src]; - int b = (int)roundToNearest (bc, base_angle - control_angle); - [self setBend:b]; - } else { - int angle = (int)roundToNearest (bc, control_angle); - if (link) { - [self setInAngle:(inAngle + angle - outAngle)]; - } - [self setOutAngle:angle]; - } -} - -- (void) moveCp1To:(NSPoint)point { - [self moveCp1To:point withWeightCourseness:0.0f andBendCourseness:0 forceLinkControlPoints:NO]; -} - -- (void) moveCp2To:(NSPoint)point withWeightCourseness:(float)wc andBendCourseness:(int)bc forceLinkControlPoints:(BOOL)link { - [self updateControls]; - - if (![self isSelfLoop]) { - [self adjustWeight:NSDistanceBetweenPoints (point, targ) withCourseness:wc]; - } - - float control_angle = [self angleOf:point relativeTo:targ]; - if (bendMode == EdgeBendModeBasic) { - float base_angle = [self angleOf:src relativeTo:targ]; - int b = (int)roundToNearest (bc, control_angle - base_angle); - [self setBend:b]; - } else { - int angle = (int)roundToNearest (bc, control_angle); - if (link) { - [self setOutAngle:(outAngle + angle - inAngle)]; - } - [self setInAngle: angle]; - } -} - -- (void) moveCp2To:(NSPoint)point { - [self moveCp2To:point withWeightCourseness:0.0f andBendCourseness:0 forceLinkControlPoints:NO]; -} - -- (void)reverse { - Node *n; - float f; - NSString *a; - - n = source; - source = target; - target = n; - - f = inAngle; - inAngle = outAngle; - outAngle = f; - - a = sourceAnchor; - sourceAnchor = targetAnchor; - targetAnchor = a; - - [self setBend:-bend]; - - dirty = YES; -} - -- (void)dealloc { - [source removeObserver:self - forKeyPath:@"style"]; - [target removeObserver:self - forKeyPath:@"style"]; -#if ! __has_feature(objc_arc) - [source release]; - [target release]; - [data release]; - [sourceAnchor release]; - [targetAnchor release]; - [super dealloc]; -#endif -} - -- (id)copyWithZone:(NSZone*)zone { - Edge *cp = [[Edge allocWithZone:zone] init]; - [cp setSource:[self source]]; - [cp setTarget:[self target]]; - [cp setSourceAnchor:[self sourceAnchor]]; - [cp setTargetAnchor:[self targetAnchor]]; - [cp setPropertiesFromEdge:self]; - return cp; -} - -+ (Edge*)edge { -#if __has_feature(objc_arc) - return [[Edge alloc] init]; -#else - return [[[Edge alloc] init] autorelease]; -#endif -} - -+ (Edge*)edgeWithSource:(Node*)s andTarget:(Node*)t { -#if __has_feature(objc_arc) - return [[Edge alloc] initWithSource:s andTarget:t]; -#else - return [[[Edge alloc] initWithSource:s andTarget:t] autorelease]; -#endif -} - -@end - -// vi:ft=objc:ts=4:noet:sts=4:sw=4 -- cgit v1.2.3