ROOT logo
// $Id: WSPoint.cxx 2400 2010-07-03 21:13:17Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

//______________________________________________________________________
// WSPoint
//
// Weaver Symbol Point. Represents one control point of a Weaver
// Symbol.  Its effect is determined by its position and orientation
// (from ZNode) and by three real parameters: mW (width), mS (spread)
// and mT (tension).

#include "WSPoint.h"
#include "WSSeed.h"
#include "WSPoint.c7"

#include <Glasses/ZQueen.h>

#include <TMath.h>

ClassImp(WSPoint);

/**************************************************************************/

void WSPoint::_init()
{
  mW = 0.1; mS = 0; mT = 1;
  mTwist = 0; mStretch = 1;

  mCoffPoint = mPrevPoint = mNextPoint = 0;
}

/**************************************************************************/

namespace
{
  inline Double_t sqr(Double_t x) { return x*x; }
}

void WSPoint::Coff(WSPoint* f)
{
  if (f == mCoffPoint)
    return;

  const ZTrans& a = RefTrans();
  const ZTrans& b = f->RefTrans();

  const Double_t *AT = a.ArrT(), *AX = a.ArrX();
  const Double_t *BT = b.ArrT(), *BX = b.ArrX();

  const Double_t d =
    TMath::Sqrt(sqr(AT[0] - BT[0]) + sqr(AT[1] - BT[1]) + sqr(AT[2] - BT[2]));
  const Double_t T1 = mT*d, T2 = f->mT*d;

  for (Int_t i=0; i<3; ++i)
  {
    const Double_t P = BT[i] - AT[i];
    const Double_t Q = T1*AX[i];
    const Double_t R = T2*BX[i] - 2*P + Q;

    TMatrixDRow row( mCoffs[i] );
    row[0] = AT[i];
    row[1] = Q;
    row[2] = P - Q - R;
    row[3] = R;
  }
  // Widths
  {
    const Double_t A = f->mS - 2*(f->mW - mW) + mS;
    TMatrixDRow row( mCoffs[3] );
    row[0] = mW;
    row[1] = mS;
    row[2] = (f->mW - mW) - mS - A;
    row[3] = A;
  }

  mCoffPoint = f;
}

/**************************************************************************/

TimeStamp_t WSPoint::Stamp(FID_t fid, UChar_t eye_bits)
{
  // Upon change also change parent's triangulation stamp (if it is a WSSeed).
  // Usually WSSeed is stored as a single display-list.

  TimeStamp_t t = PARENT_GLASS::Stamp(fid, eye_bits);
  if(fid.is_null() || fid == ZNode::FID() || fid == FID())
  {
    mCoffPoint = 0;
    if(mPrevPoint)
      mPrevPoint->mCoffPoint = 0;

    WSSeed* seed = dynamic_cast<WSSeed*>(*mParent);
    if(seed)
      seed->MarkStampReqTring();
  }
  return t;
}

/**************************************************************************/

void WSPoint::SetStretch(Float_t stretch)
{
  if(stretch > 100) stretch = 100;
  if(stretch < -100) stretch = -100;
  if(mNextPoint) {
    WSSeed* seed = dynamic_cast<WSSeed*>(*mParent);
    if(seed)
      seed->SetTrueLength(seed->GetTrueLength() + stretch - mStretch);
  }
  mStretch = stretch;
  Stamp(FID());
}

/**************************************************************************/

void WSPoint::InsertPoint(Float_t time)
{
  // Directly instantiates a new WSPoint on time-position 'time'.
  // Presumably this point is in parent-list exactly once (point is
  // added where first found + next point is correct).
  //
  // As point creation is potentially cluster-wide MIR presence is reqired
  // as well as common queen with parent.


  static const Exc_t _eh("WSPoint::InsertPoint ");

  suggest_MIR_presence(_eh, ZGlass::MC_IsFlare);

  if(*mParent == 0)
    throw(_eh + "parent not set.");
  if(mQueen != mParent->GetQueen())
    throw(_eh + "queen is not shared with parent.");

  if(mNextPoint == 0)
    throw(_eh + "can not insert at last point.");

  Int_t insert_id = -1;
  { bool found = false;
    GMutexHolder llck(mParent->RefListMutex());
    for(ZList::iterator i=mParent->begin(); i!=mParent->end(); ++i) {
      if(i->fLens == this) {
        ++i;
        if(i != mParent->end() && i->fLens == mNextPoint) {
          insert_id = i->fId;
          found = true;
          break;
        }
      }
    }
    if(!found)
      throw(_eh + "can not find insertion point.");
  }

  Coff(mNextPoint);

  WSPoint* p = new WSPoint("New point");
  const Double_t t = time, t2 = t*t, t3 = t2*t;
  {
    ZTrans& lcf = p->ref_trans();

    Double_t* Pnt = lcf.ArrT();
    Double_t* Axe = lcf.ArrX();

    for(Int_t i=0; i<3; i++) {
      const TMatrixDRow R( mCoffs[i] );
      Pnt[i] = R[0] +   R[1]*t +   R[2]*t2 + R[3]*t3;
      Axe[i] = R[1] + 2*R[2]*t + 3*R[3]*t2;
    }

    lcf.OrtoNorm3();
  }
  {
    const TMatrixDRow W( mCoffs[3] );
    p->mW = W[0] + W[1]*t + W[2]*t2 + W[3]*t3;
  }
  {
    GLensWriteHolder wlck(*mParent);
    mQueen->CheckIn(p);
    mParent->InsertById(p, insert_id);
  }
}
 WSPoint.cxx:1
 WSPoint.cxx:2
 WSPoint.cxx:3
 WSPoint.cxx:4
 WSPoint.cxx:5
 WSPoint.cxx:6
 WSPoint.cxx:7
 WSPoint.cxx:8
 WSPoint.cxx:9
 WSPoint.cxx:10
 WSPoint.cxx:11
 WSPoint.cxx:12
 WSPoint.cxx:13
 WSPoint.cxx:14
 WSPoint.cxx:15
 WSPoint.cxx:16
 WSPoint.cxx:17
 WSPoint.cxx:18
 WSPoint.cxx:19
 WSPoint.cxx:20
 WSPoint.cxx:21
 WSPoint.cxx:22
 WSPoint.cxx:23
 WSPoint.cxx:24
 WSPoint.cxx:25
 WSPoint.cxx:26
 WSPoint.cxx:27
 WSPoint.cxx:28
 WSPoint.cxx:29
 WSPoint.cxx:30
 WSPoint.cxx:31
 WSPoint.cxx:32
 WSPoint.cxx:33
 WSPoint.cxx:34
 WSPoint.cxx:35
 WSPoint.cxx:36
 WSPoint.cxx:37
 WSPoint.cxx:38
 WSPoint.cxx:39
 WSPoint.cxx:40
 WSPoint.cxx:41
 WSPoint.cxx:42
 WSPoint.cxx:43
 WSPoint.cxx:44
 WSPoint.cxx:45
 WSPoint.cxx:46
 WSPoint.cxx:47
 WSPoint.cxx:48
 WSPoint.cxx:49
 WSPoint.cxx:50
 WSPoint.cxx:51
 WSPoint.cxx:52
 WSPoint.cxx:53
 WSPoint.cxx:54
 WSPoint.cxx:55
 WSPoint.cxx:56
 WSPoint.cxx:57
 WSPoint.cxx:58
 WSPoint.cxx:59
 WSPoint.cxx:60
 WSPoint.cxx:61
 WSPoint.cxx:62
 WSPoint.cxx:63
 WSPoint.cxx:64
 WSPoint.cxx:65
 WSPoint.cxx:66
 WSPoint.cxx:67
 WSPoint.cxx:68
 WSPoint.cxx:69
 WSPoint.cxx:70
 WSPoint.cxx:71
 WSPoint.cxx:72
 WSPoint.cxx:73
 WSPoint.cxx:74
 WSPoint.cxx:75
 WSPoint.cxx:76
 WSPoint.cxx:77
 WSPoint.cxx:78
 WSPoint.cxx:79
 WSPoint.cxx:80
 WSPoint.cxx:81
 WSPoint.cxx:82
 WSPoint.cxx:83
 WSPoint.cxx:84
 WSPoint.cxx:85
 WSPoint.cxx:86
 WSPoint.cxx:87
 WSPoint.cxx:88
 WSPoint.cxx:89
 WSPoint.cxx:90
 WSPoint.cxx:91
 WSPoint.cxx:92
 WSPoint.cxx:93
 WSPoint.cxx:94
 WSPoint.cxx:95
 WSPoint.cxx:96
 WSPoint.cxx:97
 WSPoint.cxx:98
 WSPoint.cxx:99
 WSPoint.cxx:100
 WSPoint.cxx:101
 WSPoint.cxx:102
 WSPoint.cxx:103
 WSPoint.cxx:104
 WSPoint.cxx:105
 WSPoint.cxx:106
 WSPoint.cxx:107
 WSPoint.cxx:108
 WSPoint.cxx:109
 WSPoint.cxx:110
 WSPoint.cxx:111
 WSPoint.cxx:112
 WSPoint.cxx:113
 WSPoint.cxx:114
 WSPoint.cxx:115
 WSPoint.cxx:116
 WSPoint.cxx:117
 WSPoint.cxx:118
 WSPoint.cxx:119
 WSPoint.cxx:120
 WSPoint.cxx:121
 WSPoint.cxx:122
 WSPoint.cxx:123
 WSPoint.cxx:124
 WSPoint.cxx:125
 WSPoint.cxx:126
 WSPoint.cxx:127
 WSPoint.cxx:128
 WSPoint.cxx:129
 WSPoint.cxx:130
 WSPoint.cxx:131
 WSPoint.cxx:132
 WSPoint.cxx:133
 WSPoint.cxx:134
 WSPoint.cxx:135
 WSPoint.cxx:136
 WSPoint.cxx:137
 WSPoint.cxx:138
 WSPoint.cxx:139
 WSPoint.cxx:140
 WSPoint.cxx:141
 WSPoint.cxx:142
 WSPoint.cxx:143
 WSPoint.cxx:144
 WSPoint.cxx:145
 WSPoint.cxx:146
 WSPoint.cxx:147
 WSPoint.cxx:148
 WSPoint.cxx:149
 WSPoint.cxx:150
 WSPoint.cxx:151
 WSPoint.cxx:152
 WSPoint.cxx:153
 WSPoint.cxx:154
 WSPoint.cxx:155
 WSPoint.cxx:156
 WSPoint.cxx:157
 WSPoint.cxx:158
 WSPoint.cxx:159
 WSPoint.cxx:160
 WSPoint.cxx:161
 WSPoint.cxx:162
 WSPoint.cxx:163
 WSPoint.cxx:164
 WSPoint.cxx:165
 WSPoint.cxx:166
 WSPoint.cxx:167
 WSPoint.cxx:168
 WSPoint.cxx:169
 WSPoint.cxx:170
 WSPoint.cxx:171
 WSPoint.cxx:172
 WSPoint.cxx:173
 WSPoint.cxx:174
 WSPoint.cxx:175
 WSPoint.cxx:176
 WSPoint.cxx:177
 WSPoint.cxx:178
 WSPoint.cxx:179
 WSPoint.cxx:180
 WSPoint.cxx:181
 WSPoint.cxx:182
 WSPoint.cxx:183
 WSPoint.cxx:184
 WSPoint.cxx:185
 WSPoint.cxx:186