• 0
Geex

Горизонтальная линия в целых координатах рисуется двойной

Вопросы

Приветствую!

Не понятная ситуация с шириной линии. Рисую горизонтальную линию на канве толщиной толщиной 1 пиксель. 

Если линия лежит вдоль целых координат, например Y=100 то толщина линии реально получается 2 пикселя.

А если координаты дробные, например 50.5 то линия в один пиксель. Вот как это выглядит:

post-145-0-29967500-1398688559_thumb.png

Т.е. я так понимаю, что координаты канвы начинаются не с нуля, а с 0.5.

Как сделать чтобы отображение целых координат было точно в пиксель?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 ответа на этот вопрос

  • 0

Посмотрите вот эту статью: http://roman.yankovsky.me/?p=1018

 

upd от "konung": Русская версия статьи: http://roman.yankovsky.me/?p=996

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Спасибо!

 

Задача решена, через вычитание из координат половины толщины пера Canvas.Stroke.Thickness / 2, очень грубо, как здесь:

procedure TForm2.FormPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
var
  I: Integer;
begin
  if Canvas.BeginScene then
    try
      Canvas.Stroke.Thickness := 1.5;
      Canvas.Stroke.Kind := TBrushKind.bkSolid;
      Canvas.Fill.Color := TAlphaColorRec.Black;
      Canvas.Fill.Kind := TBrushKind.bkSolid;
 
      for I := 1 to 9 do
      begin
        Canvas.DrawLine(PointF(50 + I * 25 - (Canvas.Stroke.Thickness / 2), 0),
          PointF(50 + I * 25 - (Canvas.Stroke.Thickness / 2), ClientHeight), 1);
      end;
    finally
      Canvas.EndScene;
    end;
end;

К сожалению через функцию RoundLogicPointsToMatchPixel не получилось:

function TForm2.RoundLogicPointsToMatchPixel(const LogicPoints: Single;
  const AtLeastOnePixel: Boolean = False): Single;
var
  ws: IFMXWindowService;
  ScreenScale, Pixels: Single;
begin
  ws := TPlatformServices.Current.GetPlatformService(IFMXWindowService) as IFMXWindowService;
  ScreenScale := ws.GetWindowScale(Self);
 
  // Maybe you will want to use Ceil or Trunc instead of Round
  Pixels := Round(LogicPoints * ScreenScale);
 
  if (Pixels < 1) and (AtLeastOnePixel) then
    Pixels := 1.0;
 
  Result := Pixels / ScreenScale;
end;

Так как LogicPoints=ScreenScale=1 .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

В статье описаны проблемы с Андроидом, а тут Windows 7.

Не понятно почему вообще такое получается, бред какой-то.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Гость
Эта тема закрыта для публикации ответов.

  • Похожий контент

    • От Ilya.Z
      Добрый день, может туплю, или не туда копаю.. есть ли Firemonkey более менее стандартный способ рисовать на поверхности  3D фигур?
      в частности интересует сфера, есть две координаты, нужно провести чрез них линию, так что бы бы она легла на поверхность, или начертить фигуру так же лежащую на поверхности.
      или надо копать в глубь математики, и разбивать на множество отрезков, расчитывать каждую координату для каждой точки и т.д.
      ну а заливка фигур как понимаю только через материалы доступна в 3D, но можно залить ограниченную область на поверхности тогда ?
      нашел очень симпатичный пример на youtube от QuarkCube - Sketch3d, но там интерактивное рисование мышкой, и каждая линия это множество примитивов, все красиво но не совсем то )
      пытаюсь рисовать скажем планету, и показать на ней треки, области, точки:) 
    • От Jeysi Z
      Здравствуйте, для проекта понадобилось рисовать разные 3d линии в зависимости от значения переменной, сначала решил проверить на совсем простом примере, но сразу возникли проблемы. В общем, в процедуре render организован case для переменной stage, в зависимости от её значения должны рисоваться разные линии, но этого не происходит, рисуется только первоначальная линия. 
      Вот код процедуры :
      procedure TForm2.Dummy1Render(Sender: TObject; Context: TContext3D); var i:integer; begin case stage of 1:begin if Context.BeginScene then try Context.Clear(TAlphaColorRec.White); Context.DrawLine(TPoint3D.Create(3,3,0),TPoint3D.Create(3,-3,0),1,TAlphaColorRec.Black); finally Context.EndScene; end; end; 2:begin if Context.BeginScene then try Context.Clear(TAlphaColorRec.White); Context.DrawLine(TPoint3D.Create(-3,3,0),TPoint3D.Create(-3,-3,0),1,TAlphaColorRec.Black); finally Context.EndScene; end; end; end; end;  Вот скрины работы программы. Снизу отображается значение переменной stage.

      Заранее спасибо.
    • От Jeysi Z
      Здравствуйте, начал делать проект о сечениях, нарисовал на viewport3D куб, поставил на грани несколько сфер и соединил их линиями (это была часть задумки). Потом решил добавить всему этому вращение, но когда начинаю вращать всё, что рисовалось в рендере пропадает, причём при отдалении камеры всё нормально. Не подскажете, как можно это исправить?
      Вот код рендера:
      procedure TForm2.Dummy1Render(Sender: TObject; Context: TContext3D);
      begin
      if Context.BeginScene then
          try
            Context.DrawLine(TPoint3D.Create(-3,3,-3),TPoint3D.Create(3,3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,-3,-3),TPoint3D.Create(3,3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,-3,-3),TPoint3D.Create(-3,-3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(-3,3,-3),TPoint3D.Create(-3,-3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(-3,3,3),TPoint3D.Create(3,3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,-3,3),TPoint3D.Create(3,3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,-3,3),TPoint3D.Create(-3,-3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(-3,3,3),TPoint3D.Create(-3,-3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(-3,3,-3),TPoint3D.Create(-3,3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,-3,-3),TPoint3D.Create(3,-3,3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(-3,-3,3),TPoint3D.Create(-3,-3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(3,3,3),TPoint3D.Create(3,3,-3),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(Sphere1.Position.X,Sphere1.Position.Y,Sphere1.Position.Z),
            TPoint3D.Create(Sphere2.Position.X,Sphere2.Position.Y,Sphere2.Position.Z),1,TAlphaColorRec.Black);
            Context.DrawLine(TPoint3D.Create(Sphere3.Position.X,Sphere3.Position.Y,Sphere3.Position.Z),
            TPoint3D.Create(Sphere2.Position.X,Sphere2.Position.Y,Sphere2.Position.Z),1,TAlphaColorRec.Black);
          finally
            Context.EndScene;
          end;
      end;
      Вот код вращения
      procedure TForm2.Viewport3D1MouseMove(Sender: TObject; Shift: TShiftState; X,
        Y: Single);
      begin
          if ssleft in shift then
          begin
            Dummy2.RotationAngle.X:=Dummy2.RotationAngle.X-((Y-rot.Y)*0.3);
            Dummy2.RotationAngle.Y:=Dummy2.RotationAngle.Y-((X-rot.X)*0.3);
            Rot:=PointF(X,Y);
          end;
      end;
      Процедура масштабирования
      procedure TForm2.Viewport3D1MouseWheel(Sender: TObject; Shift: TShiftState;
        WheelDelta: Integer; var Handled: Boolean);
      begin
        CameraZ.Position.Z:=CameraZ.Position.Z+WheelDelta/40;
      end;
      На изображениях показано как работает программа


      И ещё один вопрос если позволите. Обнаружил, что если ставить отображение камеры и объектов на viewport3d как screen, то не получается сменить стандартную камеру. Можно ли это исправить?
      Заранее спасибо.
    • От Jeysi Z
      Здравствуйте, для проекта понадобилось рисовать линии в 3d графике, но возникла такая проблема, можете подсказать, что не так?
      Вот часть кода
      procedure TForm2.Sphere1Render(Sender: TObject; Context: TContext3D);
      var v1,v2:TPoint3D;
      begin
        if Context.BeginScene then
        try
          v1:=TPoint3D.Create(Sphere1.Position.X,Sphere1.Position.Y,Sphere1.Position.Z);
          v2:=TPoint3D.Create(Sphere2.Position.X,Sphere2.Position.Y,Sphere2.Position.Z);
          Context.drawline(v1,v2,1,TAlphaColorRec.Black);
        finally
          Context.EndScene;
        end;
      end;
      На изображении результат работы программы.

    • От Tumaso
      Столкнулся со следующей проблемой - TImage игнорирует установленные значения XRadius и YRadius у TRectangle (10.1 Berlin with update 2)
       
      Суть - мне необходимо, чтобы у TRectangle углы были немного скругленные, для этого я устанавливаю XRadius и YRadius. Внутри TRectangle расположен TImage (левый верхний угол 0,0, ширина и высота совпадают с размерами TRectangle). Когда я загружаю картинку в TImage (что в дизайнере, что программно), получается что TImage отображается с прямыми углами, игнорируя XRadius и YRadius своего родителя. Свойство ClipChildren у TRectangle установлен.
      Как сделать так, чтобы TImage скруглялся по углам? Что интересно, TCircle в этом плане работает, обрезая TImage.
    • От Роман Фил
      Привет ребят, созрел такой вопрос который меня мучает ! Вобщем пытаюсь загрузить картинку по прямой слыке с сервера. Картинка не грузится, не сохраняется не отображается. 
      Конечная платформа - Андроид. Пишу на Delphi xe 10 seatle.
      Что я делаю? при нажатии на сам компонент TImage (созданный динамически), должна грузится картинка по адресу преждевременно записанное в hint (TImage) при создании вида (http://блаблабла.jpg)
      Раньше код ниже работал сейчас нет не пойму что не так. Почему стал ковырять? потому что форма встает колом при загрузке изображений.
       
      var s: string; fs: TFileStream; begin fs := TFileStream.Create(tpath.Combine(tpath.GetDownloadsPath, 'load.jpg'), fmCreate); NetHTTPClient1.Get((Sender as TImage).Hint, fs); fs.Free; (Sender as TImage).MultiResBitmap.Bitmaps[1].LoadFromFile (tpath.Combine(tpath.GetDownloadsPath, 'load.jpg')); подключал еще pas нашел на этом форуме FMX.Features.Bitmap.Helpers.pas
      (Sender as TImage).MultiResBitmap.Bitmaps[1].LoadFromUrl ((Sender as TImage).Hint); как проще сделать посоветуете чтоб и грузилось и форма не висла?
    • От Anasazi
      Всем доброго времени суток. Возникла необходимость решить такую задачу: в таблице базы MySQL хранится список изображений и их URL. Необходимо получить этот список массивом. Затем загрузить изображения и поочередно с интервалом показать их в TImage.
      Понимаю, что получить список изображений правильнее при помощи PHP скрипта, но в каком виде скрип должен вернуть данные, чтобы в Delphi получить из них массив не знаю.
      Раньше для получения изображений использовал такую процедуру. Но вопрос, где хранить изображения перед демонстрацией их в TImage? Создавать несколько MemoryStream?
      procedure LoadWebImage(url: string; image: TBitmap);
      var
        idhttp : TNetHTTPClient;
        ms : TMemoryStream;
      begin
       IdHTTP := TNetHTTPClient.Create(nil);
        ms := TMemoryStream.Create;
        try
          idhttp.Get(url, ms);
          ms.Position := 0;
          image.LoadFromStream(ms);
        finally
          ms.Free;
          idhttp.Free;
        end;
      end;
    • От denprox
      Доброго времени суток! Подскажите, как узнать оригинальный размер картинки, загруженной в TImage ?
    • От Maximus
      Доброго всем времени суток. Хочу снова поднять вопрос про отрисовку линий на канве, обсуждавшейся здесь
      С горизонтальными и вертикальными линиями проблем нет, при смещении на половину от толщины линии всё прекрасно выглядит. Однако при отрисовке линий под различными углами такой финт не проходит: слева VCL, справа FMX

      Линия всё так же размазывается, в итоге визуально утолщается и становится не такой чёткой.
      Как всё же добиться такого же результата как на VCL? Интересует только Windows.
      const OFFSET_LINE = 0.5; ... Image.Bitmap.Canvas.BeginScene; Image.Bitmap.Canvas.Stroke.Kind := TBrushKind.Solid; Image.Bitmap.Canvas.Stroke.Thickness := 1.0; Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(10.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.DrawLine( PointF(10.0 - OFFSET_LINE, 10.0 - OFFSET_LINE), PointF(500.0 - OFFSET_LINE, 500.0 - OFFSET_LINE), 1.0); Image.Bitmap.Canvas.EndScene;  
    • От Vizit0r
      Delphi Seattle, Android 5.0.1
      Формирую картинку через ScanLine. На выходе полученный битмап рисуется на полотне TImage, на котором перед этим был нарисован Rect.
      GlobalBitmap - формированный tbitmap.
                 with ObjectPreviewImage.Bitmap.Canvas do             begin               BeginScene;               Clear(TAlphaColorRec.White);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width + 8, GlobalBitmap.Height + 8);               DrawRect(DRect, 0, 0, AllCorners,                        StealthForm.ObjectPreviewImage.AbsoluteOpacity);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width, GlobalBitmap.Height);               DrawBitmap(GlobalBitmap,DRect,                  TRectF.Create(2, 2, GlobalBitmap.Width + 2, GlobalBitmap.Height + 2), 1);               EndScene;             end;  
      Проблема собственно в чем - в андроидной версии слева и внизу рамка "съедается". В Win32 версии все отлично. На прилагаемых скриншотах это четко видно.
      Документацию читал, гугл гуглил.
       
      Что я делаю не так? Или это неизвестные подводные камни андроидного рисования на полотне?
       
      P.S. Картинка одинаковая, цвет к определенной области применяется не верно. Походу тоже андроидные приколы. Но с этим я уже разберусь.
      P.P.S. Уже разобрался с цветом - под андроидом Blue и Red в пикселе надо поменять местами. А насчет канвы - не получается никак.
      P

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу